UMBC | CMSC 313 -- Assembly Language File | Previous | Next |
int func( int a, int b, int c ) { return a + b + c; }
section .data section .bss section .text global func func: push ebp mov ebp, esp mov eax, [ ebp + 8 ] ; get a add eax, [ ebp + 12 ] ; add b add eax, [ ebp + 16 ] ; add c mov esp, ebp pop ebp ret
By using the debugger, we can run up to the call to our function and stop at the statement,
stack pointer | stack contents |
---|---|
c | |
b | |
a | |
esp-> | return address |
OK, that looks good. Now, we have to get to things and the esp register might change, so we will use the ebp register to help us. Save it first by pushing it on to the stack (push ebp):
stack pointer | stack contents |
---|---|
c | |
b | |
a | |
return address | |
esp-> | ebp |
Make the ebp register point to what the esp register points to (mov ebp, esp), that way, if the esp register changes, it does not affect how we point to the parameters. To see the acual values in a sample run, we use the debugger and get:
stack pointer | stack contents | offset |
---|---|---|
c: 0x00000003 | ebp+16 | |
b: 0x00000002 | ebp+12 | |
a: 0x00000001 | ebp+8 | |
return address: 0x08048366 | ebp+4 | |
ebp-> | old ebp: 0xbfffea28 | old ebp |
Concerning the contents, the names a, b, and c represent what I had used in the C version of func( ). The return address point to the statement:
After the return value has been calculated, it is necessary to restore the ebp register and perform a return instruction (ret).
Whatever is in the eax register is moved to the specified location, in this case, the variable w, with something like (if it were in assembly language):
Now the C program can continue along its merry way. Life is good.