unlink.s 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. .text # Section for machine istructions to be executed
  2. .global _start # Needed by ld to find his default entry point
  3. _start: # _start symbol
  4. # cmdline check
  5. pop %rax # Put number of arguments in %rax register
  6. cmp $2, %rax # Must be 2 arguments (1+executable name)
  7. jne exit_cmd_line_error # jump to error if not equal
  8. mov $263, %rax # Put "263" in %rax register. 263 = sys_unlinkat call.
  9. mov $-100, %rdi # dirfd of directory for relative paths. -100 = AT_FDCWD
  10. # special for current working directory
  11. mov 8(%rsp), %rsi # Put address of string that is the name of the file
  12. # to unlink in %rsi register. This is expected to be
  13. # the second cmdline argument of this program and is
  14. # found at %rsp + 64bit (=8byte) after the pop above.
  15. xor %rdx, %rdx # Zero %rdx register = no special flags for call
  16. syscall # Ask Linux to perform syscall index by rax
  17. test %rax, %rax # Test if return value of syscall in %rax register is
  18. # zero
  19. jz exit_zero # If yes, exit zero
  20. neg %rax # If not negate error value (linux return negative numbers
  21. # in %rax for system error (range -4096:-1)
  22. mov $10, %bl # Set to "10" the 8 low bits od %rbx register
  23. div %bl # "div" istruction works like this in this case:
  24. # %ax : %bl = %al (quotient) + %ah (reminder)
  25. # NOTE: the negated error value of sys_unlink is expected to
  26. # be *in any case* a number of two digits in decimal base.
  27. # If I divide it by "10" the quotient is the first digit
  28. # and the reminder is the second one (from left to right)
  29. mov $48, %bl # Put ASCII "0" in 8 low bits of %rbx register
  30. add %bl, %al # Add ASSCII "0" one digit number in 0-byte of %rax register
  31. add %bl, %ah # Add ASSCII "0" one digit number in 1-byte of %rax register
  32. push %ax # Push 16 low bits of %rax register (contains concatened ASCII
  33. # bits for the two digits of our error code)
  34. movb $0x0A, 2(%rsp) # Put an "endline" at %rsp + 16bit. (Put "\n" ASCII code
  35. # in stack just after the digits of our error code).
  36. # (All this is to avoid 2 sys_write calls above)
  37. # Write generic part of system error message to stderr
  38. mov $1, %rax
  39. mov $1, %rdi
  40. mov $err_msg, %rsi
  41. mov $13, %rdx
  42. syscall
  43. mov $1, %rax # Write error code digits + endline to stderr
  44. mov $1, %rdi
  45. lea (%rsp), %rsi
  46. mov $3, %rdx
  47. syscall
  48. mov $1, %rdi # Put "1" in $rax %rdi register. (1= exit code)
  49. jmp exit # Exit
  50. print_help: # Print cmdline help to stdout
  51. mov $1, %rax
  52. mov $1, %rdi
  53. mov $help_msg, %rsi
  54. mov $19, %rdx
  55. syscall
  56. ret # Return to main program execution
  57. exit: # Ask kernel to terminate execution with some exit
  58. # code
  59. mov $60, %rax # Put "60" in %rax register. 60 = sys_exit call
  60. # exit status argument of sys_exit.
  61. syscall # Ask Linux to perform syscall indexed by %rax
  62. exit_zero: # Exit with 0 exit code
  63. xor %rdi, %rdi # Set %rdi register to "0".
  64. jmp exit # Jump to "exit" routine
  65. exit_cmd_line_error: # Exit with 1 exit code printing cmdline help
  66. call print_help # Call print_help function
  67. mov $1, %rdi # Put "1" exit code in %rdi register
  68. jmp exit # Jump to "exit" routine
  69. .section .rodata
  70. help_msg: # 19 bytes; cmdline help message
  71. .ascii "Usage: unlink FILE\n"
  72. err_msg: # 13 bytes; generic string for system error
  73. .ascii "System error "