pwd.s 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  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. mov $79, %rax # Put "79" in %rax register. 79 = sys_getcwd call
  5. mov $buf, %rdi # Put the starting address of the buffer 'buf'
  6. # in %rdi register. This syscall expect this buffer
  7. # to write into the path of che cwd
  8. mov $4096, %rsi # Put in %rsi register the length of 'buf' buffer.
  9. # Is 4096 byte enough? It would be better to use
  10. # MAX_PATH
  11. syscall # Ask Linux to perform syscall indexed by %rax
  12. movb $0x0A, -1(%rdi,%rax) # A pro gamer move: substitute the trailing 0 char
  13. # of the string written in 'buf' by the kernel
  14. # sys_getcwd routine, with '\n':
  15. # * 0x0A is hex for '\n'
  16. # * After sys_getcwd %rax contains the length of the
  17. # buffer filled (which includes the ending '\0'
  18. # character)
  19. # * Addressing mode:
  20. # displacement(base,index,scale) =
  21. # base + index*scale + diplacement
  22. # +base = %rdi = contains address of 'buf'
  23. # +index = %rax = contains the # of bytes to walk
  24. # after base address to find the desired spot
  25. # in memory: the end of the space filled by getcwd
  26. # in 'buf'
  27. # +displacement = -1 = like index but fixed integer
  28. # in code: -1 to point to the last char in 'buf'
  29. # +scale = 1 = multiplier for index
  30. # * b in movb: specify that the value to be placed in
  31. # memory has the length of a byte (ASCII char)
  32. mov %rdi, %rsi # Put the starting address of the buffer 'buf'
  33. # in %rsi register (this address was put in %rdi
  34. # by a previous instruction and left unchanged by
  35. # the kernel during the routine of the last syscall:
  36. # this realization avoids the processor accessing
  37. # memory to retrieve the desired address)
  38. mov $1, %rdi # Put "1" in register %rdi. sys_write expects a
  39. # file descriptor in this register. 1 = std out
  40. mov %rax, %rdx # Put the number of byte to read from 'buf' and write
  41. # to fd. See previous code block for the content
  42. # of %rax at this point of the execution.
  43. mov $1, %rax # Put "1" in %rax register. 1 = sys_write call
  44. # NOTE: %rax was filled after the argument register %rdx
  45. # for the convenience of "mov %rax, %rdx" (avoid
  46. # access in memory)
  47. syscall # Ask Linux to perform syscall indexed by %rax
  48. mov $60, %rax # Put "60" in %rax register. 60 = sys_exit call
  49. xor %rdi, %rdi # Set %rdi register to "0". %rdi = where to put
  50. # exit status argument of sys_exit. Using the 'xor'
  51. # istruction is an optimization: avoid retrieving "0"
  52. # in memory)
  53. syscall # Ask Linux to perform syscall indexed by %rax
  54. .section .bss # Assemble the following code into bss section
  55. buf: # Define a symbol (tag) named 'buf' to identify
  56. # the starting address of a buffer in code
  57. .skip 4096 # Assemble a "space" of 4096 byte. This will be
  58. # a buffer of 4096 zeroed byte in bss segment
  59. # starting at address 'buf' during execution