Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; Allow the linker to find the _start symbol. The linker will begin program execution
- ; there.
- global _start
- ; Start the .data section of the executable, which stores constants (read-only data)
- ; It doesn't matter which order your sections are in, I just like putting .data first
- section .rodata
- ; Declare some bytes at a symbol called hello_world. NASM's db pseudo-instruction
- ; allows either a single byte value, a constant string, or a combination of the two
- ; as seen here. 0xA = new line, and 0x0 = string-terminating null
- hello_world: db "Hello world!", 0xA, 0x0
- ; Start the .text section, which stores program code
- section .text
- _start:
- enter 0, 0
- ; save the caller-saved registers (I choose to not save any)
- push hello_world ; push the argument to _print_msg
- call _print_msg
- mov eax, 0x01 ; 0x01 = exit()
- mov ebx, 0 ; 0 = no errors
- int 0x80
- _print_msg:
- enter 0, 0
- ; My function begins here
- mov eax, 0x04 ; 0x04 = the write() syscall
- mov ebx, 0x1 ; 0x1 = standard output
- mov ecx, [ebp+8] ; the string we want to print is the first argument of this function
- ; at this point we wish to set edx to the length of the string. time to call _strlen
- push eax ; save the caller-saved registers (I choose to not save edx)
- push ecx
- push dword [ebp+8] ; push _strlen's argument, the string argument to _print_msg. NASM
- ; complains if you do not put a size directive here, and I'm not sure
- ; why. Anyway, a pointer is a dword (4 bytes)
- call _strlen ; eax is now equal to the length of the string
- mov edx, eax ; move the length into edx where we wanted it
- add esp, 4 ; remove 4 bytes from the stack (one 4-byte char* argument)
- pop ecx ; restore caller-saved registers
- pop eax
- ; we're done calling _strlen and setting up the syscall
- int 0x80
- leave
- ret
- _strlen:
- enter 0, 0 ; save the previous frame's base pointer and adjust ebp
- ; Here I'd save the callee-saved registers, but I won't be modifying any
- ; My function begins here
- mov eax, 0 ; length = 0
- mov ecx, [ebp+8] ; copy the function's first argument (pointer to the first character
- ; of the string) into ecx (which is caller-saved, so no need to save it)
- _strlen_loop_start:
- cmp byte [ecx], 0 ; dereference that pointer and compare it to null. Here we have to
- ; explicitly mention it's a byte since the size of the pointer is
- ; ambiguous (is it a 4 byte integer? 2? 1?). This is called called a
- ; Size Directive
- je _strlen_loop_end ; jump out of the loop if it is equal to null
- add eax, 1 ; add 1 to our return value
- add ecx, 1 ; increment to the next character in the string
- jmp _strlen_loop_start ; jump back to the start
- _strlen_loop_end:
- ; My function ends here. eax is equal to my function's return value
- ; Here I'd restore the callee-saved registers, but I didn't save any
- leave ; deallocate and restore the previous frame's base pointer
- ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement