University of Washington
Section 5: Procedures & Stacks
Stacks in memory and stack operations
The stack used to keep track of procedure calls
Return addresses and return values
Stack-based languages
The Linux stack frame
Passing arguments on the stack
Allocating local variables on the stack
Register-saving conventions
Procedures and stacks on x64 architecture
Linux Stack Frame
University of Washington
IA32/Linux Stack Frame
Current Stack Frame (“Top” to Bottom)
“Argument build” area
(parameters for function
about to be called)
Local variables
(if can’t be kept in registers)
Saved register context
(when reusing registers)
Old frame pointer (for caller)
Caller
Frame
Arguments
Frame pointer
%ebp
Saved
Registers
+
Local
Variables
Caller’s Stack Frame
Return address
Pushed by call instruction
Arguments for this call
Return Addr
Old %ebp
Linux Stack Frame
Stack pointer
%esp
Argument
Build
University of Washington
Revisiting swap
int zip1 = 15213;
int zip2 = 98195;
void call_swap()
{
swap(&zip1, &zip2);
}
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
Linux Stack Frame
University of Washington
Revisiting swap
Calling swap from call_swap
int zip1 = 15213;
int zip2 = 98195;
call_swap:
• • •
pushl $zip2
pushl $zip1
call swap
• • •
void call_swap()
{
swap(&zip1, &zip2);
}
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
Linux Stack Frame
# Global Var
# Global Var
University of Washington
Revisiting swap
Calling swap from call_swap
int zip1 = 15213;
int zip2 = 98195;
call_swap:
• • •
pushl $zip2
pushl $zip1
call swap
• • •
void call_swap()
{
swap(&zip1, &zip2);
}
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
Linux Stack Frame
•
•
•
# Global Var
# Global Var
Resulting
Stack
&zip2
&zip1
Rtn adr
%esp
University of Washington
Revisiting swap
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
movl
movl
movl
movl
movl
movl
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
Linux Stack Frame
Set
Up
Body
Finish
University of Washington
swap Setup #1
Entering Stack
Resulting Stack?
%ebp
•
•
•
&zip2
&zip1
Rtn adr
%esp
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
Linux Stack Frame
University of Washington
swap Setup #1
Entering Stack
Resulting Stack
%ebp
%ebp
•
•
•
•
•
•
&zip2
yp
&zip1
xp
Rtn adr
%esp
Rtn adr
Old %ebp
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
Linux Stack Frame
%esp
University of Washington
swap Setup #2
Entering Stack
Resulting Stack
%ebp
•
•
•
•
•
•
&zip2
yp
&zip1
xp
Rtn adr
%esp
Rtn adr
Old %ebp
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
Linux Stack Frame
%ebp
%esp
University of Washington
swap Setup #3
Entering Stack
Resulting Stack
%ebp
•
•
•
•
•
•
&zip2
yp
&zip1
xp
Rtn adr
%esp
Rtn adr
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
Linux Stack Frame
Old %ebp
%ebp
Old %ebx
%esp
University of Washington
swap Body
Entering Stack
Resulting Stack
%ebp
•
•
•
Offset relative
to new %ebp
12
8
4
&zip2
&zip1
Rtn adr
%esp
movl 12(%ebp),%ecx
movl 8(%ebp),%edx
. . .
# get yp
# get xp
Linux Stack Frame
•
•
•
yp
xp
Rtn adr
Old %ebp
%ebp
Old %ebx
%esp
University of Washington
swap Finish #1
swap’s Stack
Resulting Stack?
•
•
•
yp
xp
Rtn adr
Old %ebp
%ebp
Old %ebx
%esp
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
Linux Stack Frame
University of Washington
swap Finish #1
swap’s Stack
Resulting Stack
•
•
•
•
•
•
yp
yp
xp
xp
Rtn adr
Rtn adr
Old %ebp
%ebp
Old %ebp
%ebp
Old %ebx
%esp
Old %ebx
%esp
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
Observation: Saved and restored
register %ebx
Linux Stack Frame
University of Washington
swap Finish #2
swap’s Stack
Resulting Stack
•
•
•
•
•
•
yp
yp
xp
xp
Rtn adr
Rtn adr
Old %ebp
%ebp
Old %ebx
%esp
Old %ebp
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
Linux Stack Frame
%ebp
%esp
University of Washington
swap Finish #3
swap’s Stack
Resulting Stack
%ebp
•
•
•
•
•
•
yp
yp
xp
xp
Rtn adr
Rtn adr
Old %ebp
%ebp
Old %ebx
%esp
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
Linux Stack Frame
%esp
University of Washington
swap Finish #4
swap’s Stack
Resulting Stack
%ebp
•
•
•
•
•
•
yp
yp
xp
xp
Rtn adr
Old %ebp
%ebp
Old %ebx
%esp
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
Linux Stack Frame
%esp
University of Washington
Disassembled swap
080483a4 <swap>:
80483a4:
55
80483a5:
89 e5
80483a7:
53
80483a8:
8b 55 08
80483ab:
8b 4d 0c
80483ae:
8b 1a
80483b0:
8b 01
80483b2:
89 02
80483b4:
89 19
80483b6:
5b
80483b7:
c9
80483b8:
c3
push
mov
push
mov
mov
mov
mov
mov
mov
pop
leave
ret
%ebp
%esp,%ebp
%ebx
0x8(%ebp),%edx
0xc(%ebp),%ecx
(%edx),%ebx
(%ecx),%eax
%eax,(%edx)
%ebx,(%ecx)
%ebx
mov
pop
%ebp,%esp
%ebp
Calling Code
8048409:
804840e:
e8 96 ff ff ff
8b 45 f8
call 80483a4 <swap>
mov 0xfffffff8(%ebp),%eax
Linux Stack Frame
University of Washington
swap Finish #4
swap’s Stack
Resulting Stack
%ebp
•
•
•
•
•
•
yp
yp
xp
xp
%esp
Rtn adr
Old %ebp
%ebp
Old %ebx
%esp
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
Observation
Saved & restored register %ebx
Didn’t do so for %eax, %ecx, or %edx
Linux Stack Frame