writing functions in assembler
Here is a new, very easy way to write functions in assembly (with many return values):
function:
sub esp, ( 4 * ret_count)
pushad
mov ebp, esp
;code
;acces first argument with ( dword[ebp + 32 + (4*ret_count) + (4*arg_num)]
;write first return value with ( mov dword[ebp + 36 + (4*ret_pointer)]
popad
add esp, ( 4 * ret_count)
ret
After that, you can access return values like this:
call function
mov eax, dword[esp] ; 1st ret
mov ebx, dword[esp - 4] ; 2nd ret
; or you can just pop them :
pop eax
pop ebx
(assuming NASM x86)
Use call
in order to call the function and ret
to return from the function.
What occurs when you type call
is that the address of the next instruction is push
ed into the stack. When ret
is hit, it will pop
that address off the stack and jmp
to it.
func:
xor eax, eax
mov eax, 10
add eax, 5
ret ;// essentially identical to: pop [register] -> jmp [register]
_start:
call func
mov ebx, eax ;// Address of this instruction is pushed onto the stack
;// ebx is now 15
Calling convention dictates that the EAX
register should contain the return value. Also note that the __cdecl calling convention takes parameters on the stack. Take a look at the examples in the afore-linked page. The NASM function will set up its stack frame and take parameters from the stack in order to use in the function. The value is stored in EAX
.