IA32/Linux Stack • Memory managed with stack discipline • Register %esp stores the address of top element
0x0
Procedure Calls Instructions Functions pushl src Fetch data at src
CS 217
Decrement %esp by 4 movl src, (%esp) popl dest
Stack pointer %esp
Top Top element
movl (%esp), dest Increment %esp by 4 Bottom
1
Procedure Calls
Procedure Calls
• Calling a procedure involves following actions o o o o o
2
• Requirements o o o o o o o
pass arguments save a return address transfer control to callee transfer control back to caller return results int add3(int a, int b, int c) { return a + b + c; }
Make a call to an arbitrary address Return back after the call sequence Handle nested procedure calls Save and restore caller’s registers Pass an arbitrary number of arguments Pass and return structures Allocate and deallocate space for local variables
• Procedure call and return instruction sequences collaborate to implement these requirements
foo(void) { int d; d = add3( 3, 4, 5 ); return d; } 3
4
Procedure Calls
Call and Return Instructions
• Requirements ¾ ¾ o o o o o
• Procedure call
Make a call to an arbitrary address Return back after the call sequence Handle nested procedure calls Save and restore caller’s registers Pass an arbitrary number of arguments Pass and return structures Allocate and deallocate space for local variables
o Push the return address on the stack o Jump to the procedure location
0
• Procedure return o Pop the return address off the stack o Jump to the return address
• Why using a stack?
• Procedure call and return instruction sequences collaborate to implement these requirements
Instructions Functions call addr pushl %eip jmp addr ret
Stack pointer %esp
Old eip
pop %eip Bottom
5
Nested Procedure Call
Procedure Calls
• A calls B, which calls C
• Requirements o o ¾ ¾ o o o
• Must even work when B is A A:
C:
B:
call B
6
call C
Make a call to an arbitrary address Return back after the call sequence Handle nested procedure calls Save and restore caller’s registers Pass an arbitrary number of arguments Pass and return structures Allocate and deallocate space for local variables
• Procedure call and return sequences collaborate to implement these requirements ret
ret
ret
7
8
Procedure Stack Structure
Stack Frame in Detail • Callee stack frame
• Stack frame
o Parameters for called functions o Local variables – If can’t keep in registers o Saved register context o Old frame pointer
o Each procedure call has a stack frame o Deal with nested procedure calls 0x0
• Stack Pointer
•
o Register %esp o Point to the top element of the stack Stack pointer Frame Pointer (%esp) o Register %ebp Frame pointer o Start of current stack frame (%ebp)
• Caller stack frame o Return address – Pushed by “call” instruction o Arguments for this call
Stack frame
• Before return, use “leave” instruction, which does
Stack frame
• Why using a frame pointer? o Pop off the entire frame before the procedure call returns
(%esp)
Callee frame (%ebp)
Arguments
Caller frame
movl %ebp, %esp popl %ebp
Stack frame
Local variables Saved registers Old ebp Return addr
Local variables Saved registers Old ebp
9
Procedure (Callee)
10
Procedure (Callee) in Action
.text
.text
.globl Foo
.globl Foo
Foo:
Foo:
pushl %ebp movl %esp, %ebp . . . leave
Callee frame (%ebp)
movl %ebp, %esp popl %ebp
movl %esp, %ebp . . . leave
Local variables Saved registers Old ebp Return addr Arguments
Caller frame
ret
pushl %ebp
(%esp)
movl %ebp, %esp popl %ebp 11
(%ebp) (%esp) (%ebp) (%esp) (%esp)
Local variables Saved registers Old ebp Return addr Arguments
Caller frame
ret
Local variables Saved registers Old ebp
(%esp)
(%ebp)
Local variables Saved registers Old ebp
12
Register Saving Options • Problem: a procedure needs to use registers, but o If you use the registers, their contents will be changed when returning to the caller o If we save registers on the stack, who is responsible?
IA32/Linux Register Saving Convention • Special stack registers
main: • • • movl $0x123, %edx call Foo addl %edx, %eax • • • ret
o %ebp, %esp
• Callee-save registers o %ebx, %esi, %edi o Old values saved on stack prior to using
• Caller-save registers
• Caller Save o Caller saves registers in its frame before calling
• “Callee Save” o Callee saves registers in its frame before using
%eax Caller-Save registers
%ecx %ebx Callee-Save registers
o %eax, %edx, %ecx o Save on stack prior to calling
Foo: • • • movl 8(%ebp), %edx addl $0x456, %edx • • • ret
%edx
%esi %edi %esp
Stack
%ebp
13
Procedure Calls
Passing Arguments to Procedure
• Requirements o o o o ¾ ¾ ¾
14
• Arguments are passed on stack in order
Set PC to arbitrary address Return PC to instruction after call sequence Handle nested procedure calls Save and restore caller’s registers Pass an arbitrary number of arguments Pass and return structures Allocate and deallocate space for local variables
0x0
o Push N-th argument first o Push 1st argument last
• Callee references the argument by o 1st argument: 8(%ebp) o 2nd argument: 12(%ebp) o ...
• Procedure call and return sequences collaborate to implement these requirements
• Passing result back by %eax o Caller is responsible for saving %eax register
15
(%esp)
Callee frame (%ebp)
Caller frame
Arguments build Local variables Saved registers Old ebp Return addr Arg1 .. . ArgN Local variables Saved registers Old ebp 16
Example: Passing Arguments
Allocation for Local Variables
.text .globl add3
int d;
• Local variables are stored in a stack frame
add3: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax addl 8(%ebp), %eax addl 16(%ebp), %eax leave ret .globl foo
int add3(int a, int b, int c) { return a + b + c; }
• Allocation is done by moving the stack pointer %esp subl $4, %esp
• Reference local variable by using register %ebp
foo:
foo(void) { d = add3( 3, 4, 5 ); return d; }
pushl movl pushl pushl pushl call movl leave ret .comm
%ebp %esp, %ebp $5 $4 $3 add3 %eax, d
d,4,4
{ return a + b + c; }
foo(void) { int d; d = add3( 3, 4, 5 ); return d; }
.text .globl add3 add3: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax addl 8(%ebp), %eax addl 16(%ebp), %eax leave ret .globl foo foo: pushl %ebp movl %esp, %ebp subl $4, %esp pushl $5 pushl $4 pushl $3 call add3 movl %eax, -4(ebp) leave ret
(%esp)
Callee frame (%ebp)
e.g. -4(%ebp)
Caller frame
Arguments build Local variables Saved registers Old ebp Return addr Arg1 .. . ArgN Local variables Saved registers Old ebp
17
Example: Local Variables int add3(int a, int b, int c)
0x0
18
Summary • Issues related to calling conventions o o o o o o
Stack frame for caller and callee Use esp and ebp registers Passing arguments on stack Saving registers on stack (caller save and callee save) Local variables on stack Passing result in eax register
• Procedure call instructions call, ret, leave
19
20