1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586 |
- .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 "
|