The following code calls a subprogram to add three numbers sent as parameters and returns the sum to the caller.
; main calls addemup(5, 3, 7) and prints result
extern printf
segment .data
myformat db "addemup returned %d",10,0
check db "first param is %d",10,0 ; used by addemup
segment .text
global main
main:
push ebp
mov ebp, esp
push 7 ; args pushed right to left
push 3
push 5
call addemup ; eax = addemup(5, 3, 7)
add esp, 12
; print out result from subroutine (in eax by convention)
push eax
push myformat
call printf
add esp, 8
mov eax, 0
mov esp, ebp
pop ebp
ret
addemup:
push ebp ; save the old ebp on the stack
mov ebp, esp ; set new ebp for addemup stack frame
; at this point, [ebp] is old ebp and [ebp+4] is old eip
; let's print the first parameter to help determine the order
mov eax, [ebp + 8]
push eax
push check
call printf
add esp, 8
; do the adding and make sure final answer lands in eax
mov eax, [ebp + 8]
add eax, [ebp + 12]
add eax, [ebp + 16]
mov esp, ebp ; restore original (main's) esp
pop ebp ; restore original (main's) ebp
ret ; this will restore original eip
here is another version of this program that makes use of local variables in both subprograms
; demonstrate use of local variables
; int main()
; {
; int a = 5, b = 3, c = 7;
; int ret;
; ret = addemup(a, b, c);
; print ret;
; return 0;
; }
; int addemup(int x, int y, int z)
; {
; int ans = 0;
; ans = x + y + z;
; return ans;
; }
extern printf
segment .data
output db "ret=%d",10,0
segment .text
global main
main:
push ebp
mov ebp, esp
sub esp, 16 ; allocate space for 4 32-bit int local variables
; get to local vars by subtracting from ebp, e.g. [ebp-4], [ebp-8], etc
; so, by convention,
; a is at [ebp-4], b is [ebp-8], c is [ebp-12], ret is [ebp-16]
; initialize local variables
mov dword [ebp-4], 5
mov dword [ebp-8], 3
mov dword [ebp-12], 7
push dword [ebp-12] ; push c
push dword [ebp-8]
push dword [ebp-4]
call addemup ; eax = addemup(a,b,c)
add esp, 12
mov dword [ebp-16], eax ; ret = eax
push dword [ebp-16]
push output
call printf ; print ret
add esp, 8
add esp, 16 ; de-allocate space for local variables
mov eax, 0
mov esp, ebp
pop ebp
ret
addemup:
push ebp
mov ebp, esp
sub esp, 4 ; ans is at [ebp-4]
mov eax, [ebp + 8]
add eax, [ebp + 12]
add eax, [ebp + 16]
mov dword [ebp-4], eax ; ans = eax
mov eax, dword [ebp-4] ; get return value in eax
add esp, 4 ; de-allocate space for local variables
mov esp, ebp
pop ebp
ret