Advertisement
Guest User

Untitled

a guest
Mar 25th, 2019
50
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.24 KB | None | 0 0
  1. ; Allow the linker to find the _start symbol. The linker will begin program execution
  2. ; there.
  3. global _start
  4.  
  5. ; Start the .data section of the executable, which stores constants (read-only data)
  6. ; It doesn't matter which order your sections are in, I just like putting .data first
  7. section .rodata
  8. ; Declare some bytes at a symbol called hello_world. NASM's db pseudo-instruction
  9. ; allows either a single byte value, a constant string, or a combination of the two
  10. ; as seen here. 0xA = new line, and 0x0 = string-terminating null
  11. hello_world: db "Hello world!", 0xA, 0x0
  12.  
  13. ; Start the .text section, which stores program code
  14. section .text
  15. _start:
  16. enter 0, 0
  17. ; save the caller-saved registers (I choose to not save any)
  18. push hello_world ; push the argument to _print_msg
  19. call _print_msg
  20. mov eax, 0x01 ; 0x01 = exit()
  21. mov ebx, 0 ; 0 = no errors
  22. int 0x80
  23.  
  24.  
  25. _print_msg:
  26. enter 0, 0
  27. ; My function begins here
  28. mov eax, 0x04 ; 0x04 = the write() syscall
  29. mov ebx, 0x1 ; 0x1 = standard output
  30. mov ecx, [ebp+8] ; the string we want to print is the first argument of this function
  31. ; at this point we wish to set edx to the length of the string. time to call _strlen
  32. push eax ; save the caller-saved registers (I choose to not save edx)
  33. push ecx
  34. push dword [ebp+8] ; push _strlen's argument, the string argument to _print_msg. NASM
  35. ; complains if you do not put a size directive here, and I'm not sure
  36. ; why. Anyway, a pointer is a dword (4 bytes)
  37. call _strlen ; eax is now equal to the length of the string
  38. mov edx, eax ; move the length into edx where we wanted it
  39. add esp, 4 ; remove 4 bytes from the stack (one 4-byte char* argument)
  40. pop ecx ; restore caller-saved registers
  41. pop eax
  42. ; we're done calling _strlen and setting up the syscall
  43. int 0x80
  44. leave
  45. ret
  46.  
  47.  
  48. _strlen:
  49. enter 0, 0 ; save the previous frame's base pointer and adjust ebp
  50. ; Here I'd save the callee-saved registers, but I won't be modifying any
  51. ; My function begins here
  52. mov eax, 0 ; length = 0
  53. mov ecx, [ebp+8] ; copy the function's first argument (pointer to the first character
  54. ; of the string) into ecx (which is caller-saved, so no need to save it)
  55. _strlen_loop_start:
  56. cmp byte [ecx], 0 ; dereference that pointer and compare it to null. Here we have to
  57. ; explicitly mention it's a byte since the size of the pointer is
  58. ; ambiguous (is it a 4 byte integer? 2? 1?). This is called called a
  59. ; Size Directive
  60. je _strlen_loop_end ; jump out of the loop if it is equal to null
  61. add eax, 1 ; add 1 to our return value
  62. add ecx, 1 ; increment to the next character in the string
  63. jmp _strlen_loop_start ; jump back to the start
  64. _strlen_loop_end:
  65. ; My function ends here. eax is equal to my function's return value
  66. ; Here I'd restore the callee-saved registers, but I didn't save any
  67. leave ; deallocate and restore the previous frame's base pointer
  68. ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement