CSC 24: Computer Systems Using the Stack for Function Calls Lecture Goals Challenges of supporting functions! Providing information for the called function Function arguments and local variables! Allowing the calling function to continue where it left off Return address and contents of registers Stack: last-in-first-out data structure! Stack frame: args, local vars, return address, registers! Stack pointer: pointing to the current top of the stack Calling functions! CALL and instructions! PUSH into and POP from the stack frame! Using the base pointer as a reference point 1
Function Calls main calls add3! Push arguments on the stack! Push return address on stack! Jump to add3! Allocate local variables on stack, save registers, etc. Return Address int add3(int a, int b, int c) { int d; } d = a + b + c; return d; int main() { int sum, avg; } sum = add3(3, 4, 5); avg = sum / 3; return avg Returning to main! Clear the stack frame for add3! Pop return address from stack for add3 Return Address 3 4 5 for main s High-Level Picture main begins executing main calls P (Extended Stack Pointer) Always points to the top element of the stack Bottom main s 2
High-Level Picture main begins executing main calls P P calls Q Bottom P s main s High-Level Picture main begins executing main calls P P calls Q Q returns Bottom Q s P s main s 3
High-Level Picture main begins executing main calls P P calls Q Q returns P returns Bottom P s main s High-Level Picture main begins executing main calls P P calls Q Q returns P returns main returns Bottom main s 4
High-Level Picture main begins executing main calls P P calls Q Q returns P returns main returns Bottom Function Call Details Call and Return instructions! CALL: push EIP on the stack, and jump to function! : pop the stack into the EIP to go back Function arguments get placed onto the stack before CALL 5
CALL Called function can address arguments relative to : as [+4] before CALL after CALL EIP(caller) : Returning to Caller before EIP(caller) after 6
Base Pointer: As Callee executes, may change! e.g., preparing to call another function How to access arguments then?! Use as fixed reference Need to save old value of! Before overwriting register Callee begins by executing prolog PUSH,, (caller) EIP(caller) Base Pointer: Before returning, Callee must restore to its old value Executes, (caller) EIP(caller) 7
Base Pointer: Before returning, Callee must restore to its old value Executes,, (caller) EIP(caller) Base Pointer: Before returning, Callee must restore to its old value Executes, EIP(caller) 8
Base Pointer: Before returning, Callee must restore to its old value Executes, Allocation for Local Variables Local variables of the Callee are also allocated on the stack Allocation done by moving the stack pointer Example: allocate two integers! SUB, 4! SUB, 4! (or equivalently, SUB, 8) Reference local variables using the base pointer! [-4]! [-8] Var 2 Var 1 (caller) EIP(caller) 9
A Simple Example int sum(int x, int y) { return x+y; } int main () { int result; } result = sum(, ); printf("%d\n", result); return ; Compile: gcc sum.c o xsum Debug: gdb./xsum set disassembly-flavor intel disas main Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 Recall that:! The stack grows from high addresses towards low addresses (os) 1
Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 (os) Recall that:! The stack grows from high addresses towards low addresses (os) Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 (os) (main)
Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 (os) (main) Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 (os) (main) 12
Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 <sum>: PUSH ADD POP, EAX, DWORD PTR [+12] EAX, DWORD PTR [+8] (os) (main) Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], RA(main) DWORD PTR [-4],EAX EAX, ADD, 16 RA(main) <sum>: PUSH ADD POP, EAX, DWORD PTR [+12] EAX, DWORD PTR [+8] (os) (main) 13
Example RA(main) PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 (main) RA(main) <sum>: PUSH ADD POP, EAX, DWORD PTR [+12] EAX, DWORD PTR [+8] (os) (main) Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], RA(main) DWORD PTR [-4],EAX EAX, ADD, 16 (main) RA(main) (sum) <sum>: PUSH ADD POP, EAX, DWORD PTR [+12] EAX, DWORD PTR [+8] (os) (main) 14
Example RA(main) PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 (main) RA(main) (sum) <sum>: PUSH ADD POP, EAX, DWORD PTR [+12] EAX, DWORD PTR [+8] (os) EAX (main) Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], RA(main) DWORD PTR [-4],EAX EAX, ADD, 16 (main) RA(main) (sum) <sum>: PUSH ADD POP, EAX, DWORD PTR [+12] EAX, DWORD PTR [+8] (os) EAX 33 (main) 15
Example RA(main) PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 RA(main) <sum>: PUSH ADD POP, EAX, DWORD PTR [+12] EAX, DWORD PTR [+8] (os) EAX 33 (main) Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 (os) (main) EAX 33 16
Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 33 (os) (main) Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 33 (os) (main) Prepare to: leave EAX 17
Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 (os) (main) EAX Example PUSH, SUB, 16 DWORD PTR [+4], DWORD PTR [], DWORD PTR [-4],EAX EAX, ADD, 16 (os) EAX 18
Summary Invoking a function! CALL: call the function! : return from the instruction for a function call includes! Function arguments! Return address! Local variables! Saved registers Base pointer! Fixed reference point in the! Useful for referencing arguments and local variables 19