CSC 2400: Computer Systems Using the Stack for Function Calls - - PowerPoint PPT Presentation
CSC 2400: Computer Systems Using the Stack for Function Calls - - PowerPoint PPT Presentation
CSC 2400: Computer Systems Using the Stack for Function Calls Lecture Goals int add3(int a, int b, int c) { int d; How are function calls d = a + b + c; implemented at the return d; } machine level? int main() { int sum, avg;
Lecture Goals
- Challenges:
! Providing info for the called function – Function arguments – Local variables ! Upon return, resume execution of caller – Return address – Register contents
- Solution: use the stack
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 }
How are function calls implemented at the machine level?
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
- Solution: use the stack
! Stack frame: args, local vars, return address, registers ! Stack pointer ESP: pointing to the current top of the stack
- Calling functions
! CALL and RET instructions ! Using the base pointer EBP as a reference point
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.
- Returning to main
! Clear the stack frame for add3 ! Pop return address from stack
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 }
Return Addr. Address
ESP
5 4 3 Stack Frame for add3
Return Address
Stack Frame for main
The Stack
q The stack is a region of your
executable program used to facilitate function calls
- it stores function arguments,
local variables, etc.
q The register ESP always
points to (contains the address of) the top stack element
ESP = Extended Stack Pointer
Always points to the top element of the stack
HEAP TEXT DATA MEMORY
7
23 5 11
ESP
STACK 1 2 . . .
Function Calls
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 }
How are function calls implemented in assembly?
Stack Frames
Bottom
q The stack frame, also known as
activation record, is the collection
- f all data on the stack
associated with one function call
q The stack frame includes local
variables, arguments passed to functions, saved registers, etc.
int main() { int sum = 0,avg = 0; sum = add3(3, 4, 5); avg = sum / 3; return avg }
ESP
3 4 5 0 (avg) 0 (sum)
Stack Frame for main
Stack Frames – High-Level Picture
main begins executing main calls A main’s Stack Frame
(Extended Stack Pointer)
ESP EBP
(Extended Base Pointer)
High-Level Picture
main begins executing main calls A A calls B main’s Stack Frame A’s Stack Frame
Bottom ESP EBP
High-Level Picture
main begins executing main calls A A calls B B returns main’s Stack Frame A’s Stack Frame B’s Stack Frame
Bottom ESP EBP
High-Level Picture
main begins executing main calls A A calls B A returns B returns main’s Stack Frame A’s Stack Frame
Bottom ESP EBP
High-Level Picture
main begins executing main calls A A calls B A returns B returns main returns main’s Stack Frame
ESP EBP
High-Level Picture
main begins executing main calls P P calls Q Q returns P returns main returns
Bottom
Function Calls
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 }
How are function calls implemented in assembly?
Let’s look at the disassembled code
Disassembled code for main:
int main() { int sum, avg; sum = add3(3, 4, 5); avg = sum / 3; return avg }
ESP
5 4 3
... <main+17>: mov DWORD PTR [esp+0x8],0x5 <main+25>: mov DWORD PTR [esp+0x4],0x4 <main+33>: mov DWORD PTR [esp],0x3 <main+40>: call 0x8048394 <add3> <main+45>: mov DWORD PTR [ebp-0xc],eax ...
Stack before call <add3>
ESP+4 ESP+8
- main prepares to call add3
! place arguments on the stack
Disassembled code for main:
int main() { int sum, avg; sum = add3(3, 4, 5); avg = sum / 3; return avg }
main+45
5 4 3 Stack Frame for main
... <main+17>: mov DWORD PTR [esp+0x8],0x5 <main+25>: mov DWORD PTR [esp+0x4],0x4 <main+33>: mov DWORD PTR [esp],0x3 <main+40>: call 0x8048394 <add3> <main+45>: mov DWORD PTR [ebp-0xc],eax ...
return address (EIP)
- call <add3>
! Push return address on stack ! Jump to add3
ESP
Stack after call <add3> Stack Frame for add3
Disassembled code for add3:
main+45
ESP
5 (c) 4 (b) 3 (a) (return address)
<add3+0>: push ebp <add3+1>: mov ebp,esp <add3+3>: sub esp,0x10 <add3+6>: mov edx,DWORD PTR [ebp+0xc] <add3+9>: mov eax,DWORD PTR [ebp+0x8] <add3+12>: add eax,edx <add3+14>: add eax,DWORD PTR [ebp+0x10] ... <add3+23>: leave <add3+24>: ret
int add3(int a, int b, int c) { int d; d = a + b + c; return d; }
This is how the stack looks like before add3 starts executing ebp (copy) main+45
5 (c) 4 (b) 3 (a)
EBP ESP ESP EBP+4 EBP+8 EBP+12 EBP+16
In general …
CALL instruction
ESP after CALL Arg N Arg 1 Arg …
Return Address
ESP before CALL Arg N Arg 1 Arg … Arguments placed onto the stack before CALL CALL: push EIP on the stack and jump to callee EBP EBP
Called Function uses Base Pointer EBP
- As called function executes,
ESP may change
! e.g., calling another function
- How to access arguments?
! Use EBP as fixed reference ! Save old EBP value first
- Callee begins by executing
PUSH EBP MOV EBP, ESP ESP Arg N Arg 1 Arg …
Return Address Old EBP EBP EBP+4 EBP+8
Callee always finds the first argument at address EBP+8, second argument at address EBP+12, etc.
Old EBP
Allocation for Local Variables
EBP Arg N Arg 1 Arg …
- Local variables are also
allocated on the stack
- Allocation done by moving the
stack pointer
- Example: allocate two integers
! SUB ESP, 4 ! SUB ESP, 4 ! (or equivalently SUB ESP, 8)
- Reference local variables
using the base pointer
! [EBP-4] ! [EBP-8] EBP-8 Var 1 Var 2
Return Address Old EBP
EBP-4 EBP+8
Return Address Old EBP
EBP Arg N Arg 1 Arg …
Called function ends by executing
LEAVE RET Arg N Arg 1 Arg …
Return Address
EBP
Stack before LEAVE Stack after LEAVE
ESP ESP
Return Address
Arg N Arg 1 Arg …
Called function ends by executing
LEAVE RET Arg N Arg 1 Arg … EBP
Stack before RET Stack after RET
EBP ESP ESP Return Address copied into EIP
int sum(int x, int y) { return x+y; } int main () { int result; result = sum(0x11, 0x22); printf("%d\n", result); return 0; }
Compile: gcc sum.c –o xsum Debug: gdb ./xsum
set disassembly-flavor intel disas main
A Simple Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
ESP
Example
- Recall that:
! The stack grows from high addresses towards low addresses
ESP
Example
- Recall that:
! The stack grows from high addresses towards low addresses
EBP(os) main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
ESP
EBP(os)
EBP(main)
Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
ESP
EBP(os)
EBP(main)
Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
ESP
0x22 EBP(os)
EBP(main)
Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET <sum>: PUSH EBP MOV EBP, ESP MOV EAX, DWORD PTR [EBP+12] ADD EAX, DWORD PTR [EBP+8] POP EBP RET
ESP
0x11 0x22 EBP(os)
EBP(main)
Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET <sum>: PUSH EBP MOV EBP, ESP MOV EAX, DWORD PTR [EBP+12] ADD EAX, DWORD PTR [EBP+8] POP EBP RET
RA
ESP
RA 0x11 0x22 EBP(os)
EBP(main) (return address)
Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET <sum>: PUSH EBP MOV EBP, ESP MOV EAX, DWORD PTR [EBP+12] ADD EAX, DWORD PTR [EBP+8] POP EBP RET
RA
EBP(main) RA 0x11 0x22 EBP(os)
EBP(main) (return address) ESP
Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET <sum>: PUSH EBP MOV EBP, ESP MOV EAX, DWORD PTR [EBP+12] ADD EAX, DWORD PTR [EBP+8] POP EBP RET
RA
EBP(main) RA 0x11 0x22 EBP(os)
EBP(main) (return address) ESP EBP(sum)
Example
0x22
EAX
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET <sum>: PUSH EBP MOV EBP, ESP MOV EAX, DWORD PTR [EBP+12] ADD EAX, DWORD PTR [EBP+8] POP EBP RET
RA
EBP(main) RA 0x11 0x22 EBP(os)
EBP(main) (return address) ESP EBP(sum)
Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET <sum>: PUSH EBP MOV EBP, ESP MOV EAX, DWORD PTR [EBP+12] ADD EAX, DWORD PTR [EBP+8] POP EBP RET 0x33
EAX
RA
EBP(main) RA 0x11 0x22 EBP(os)
EBP(main) (return address) ESP EBP(sum)
Example
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET <sum>: PUSH EBP MOV EBP, ESP MOV EAX, DWORD PTR [EBP+12] ADD EAX, DWORD PTR [EBP+8] POP EBP RET 0x33
EAX
RA
RA 0x11 0x22 EBP(os)
EBP(main) (return address) ESP
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
Example
0x33
EAX
0x11 0x22 EBP(os)
EBP(main) ESP
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
Example
0x11 0x22 0x33 EBP(os)
EBP(main) ESP
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
Example
EAX
Prepare to: leave
0x11 0x22 EBP(os)
EBP(main) ESP
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
Example
EAX
EBP(os)
EBP(main) ESP
main: PUSH EBP MOV EBP,ESP ... SUB ESP, 0x14 MOV DWORD PTR [ESP+4], 0x22 MOV DWORD PTR [ESP], 0x11 CALL sum MOV DWORD PTR [EBP-4],EAX ... MOV EAX, 0 ADD ESP, 0x14 POP EBP RET
Example
EAX ESP
Summary
- Invoking a function
! CALL: call the function ! RET: return from the instruction
- Stack Frame for a function call includes
! Function arguments ! Return address ! Local variables ! Saved registers
- Base pointer EBP