.text # Section for machine istructions to be executed .global _start # Needed by ld to find his default entry point _start: # _start symbol # cmdline check pop %rax # Put number of arguments in %rax register cmp $2, %rax # Must be 2 arguments (1+executable name) jne exit_cmd_line_error # jump to error if not equal mov $263, %rax # Put "263" in %rax register. 263 = sys_unlinkat call. mov $-100, %rdi # dirfd of directory for relative paths. -100 = AT_FDCWD # special for current working directory mov 8(%rsp), %rsi # Put address of string that is the name of the file # to unlink in %rsi register. This is expected to be # the second cmdline argument of this program and is # found at %rsp + 64bit (=8byte) after the pop above. xor %rdx, %rdx # Zero %rdx register = no special flags for call syscall # Ask Linux to perform syscall indexed by rax test %rax, %rax # Test if return value of syscall in %rax register is # zero jz exit_zero # If yes, exit zero neg %rax # If not negate error value (Linux returns negative numbers # in %rax for system error (range -4096:-1) mov $10, %bl # Set to "10" the 8 low bits od %rbx register div %bl # "div" istruction works like this in this case: # %ax : %bl = %al (quotient) + %ah (reminder) # NOTE: the negated error value of sys_unlink is expected to # be *in any case* a number of two digits in decimal base. # If I divide it by "10" the quotient is the first digit # and the reminder is the second one (from left to right) mov $48, %bl # Put ASCII "0" in 8 low bits of %rbx register add %bl, %al # Add ASSCII "0" to the one digit number in 0-byte of %rax register add %bl, %ah # Add ASSCII "0" to the one digit number in 1-byte of %rax register push %ax # Push 16 low bits of %rax register (contains concatened ASCII # bits for the two digits of our error code) movb $0x0A, 2(%rsp) # Put an "endline" at %rsp + 16bit. (Put "\n" ASCII code # in stack just after the digits of our error code). # (All this is to avoid 2 sys_write calls above) # Write generic string for system error message to stderr mov $1, %rax mov $1, %rdi mov $err_msg, %rsi mov $13, %rdx syscall mov $1, %rax # Write error code digits + endline to stderr mov $1, %rdi lea (%rsp), %rsi mov $3, %rdx syscall mov $1, %rdi # Put "1" in $rax %rdi register. (1= exit code) jmp exit # Exit print_help: # Print cmdline help to stdout mov $1, %rax mov $1, %rdi mov $help_msg, %rsi mov $19, %rdx syscall ret # Return to main program execution exit: # Ask kernel to terminate execution with some exit # code mov $60, %rax # Put "60" in %rax register. 60 = sys_exit call syscall # Ask Linux to perform syscall indexed by %rax exit_zero: # Exit with 0 exit code xor %rdi, %rdi # Set %rdi register to "0". jmp exit # Jump to "exit" routine exit_cmd_line_error: # Exit with 1 exit code printing cmdline help call print_help # Call print_help function mov $1, %rdi # Put "1" exit code in %rdi register jmp exit # Jump to "exit" routine .section .rodata # Section for read-only data help_msg: # 19 bytes; cmdline help message .ascii "Usage: unlink FILE\n" err_msg: # 13 bytes; generic string for system error .ascii "System error "