IA32/Linux Stack Procedure Calls Procedure Calls

advertisement
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
Download