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 Caller
about to be called) Frame
Local variables
Arguments
(if can’t be kept in registers)
Saved register context Frame pointer Return Addr
(when reusing registers) %ebp Old %ebp
Old frame pointer (for caller)
Saved
Registers
Caller’s Stack Frame +
Return address Local
Variables
Pushed by call instruction
Arguments for this call
Argument
Stack pointer
Build
%esp
Linux Stack Frame
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; call_swap:
int zip2 = 98195; • • •
pushl $zip2 # Global Var
void call_swap() pushl $zip1 # Global Var
{ 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; call_swap:
int zip2 = 98195; • • •
pushl $zip2 # Global Var
void call_swap() pushl $zip1 # Global Var
{ call swap
swap(&zip1, &zip2); • • •
}
Resulting
• Stack
void swap(int *xp, int *yp) •
{ •
int t0 = *xp;
int t1 = *yp; &zip2
*xp = t1;
&zip1
*yp = t0;
} Rtn adr %esp
Linux Stack Frame
University of Washington
Revisiting swap
swap:
pushl %ebp
void swap(int *xp, int *yp) movl %esp,%ebp Set
{ pushl %ebx Up
int t0 = *xp;
int t1 = *yp; movl 12(%ebp),%ecx
*xp = t1; movl 8(%ebp),%edx
*yp = t0; movl (%ecx),%eax
} Body
movl (%edx),%ebx
movl %eax,(%edx)
movl %ebx,(%ecx)
movl -4(%ebp),%ebx
movl %ebp,%esp Finish
popl %ebp
ret
Linux Stack Frame
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 %esp
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
Linux Stack Frame
University of Washington
swap Setup #2
Entering Stack Resulting Stack
%ebp
• •
• •
• •
&zip2 yp
&zip1 xp
Rtn adr %esp Rtn adr
Old %ebp %ebp
%esp
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
Linux Stack Frame
University of Washington
swap Setup #3
Entering Stack Resulting Stack
%ebp
• •
• •
• •
&zip2 yp
&zip1 xp
Rtn adr %esp Rtn adr
Old %ebp %ebp
Old %ebx %esp
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
Linux Stack Frame
University of Washington
swap Body
Entering Stack Resulting Stack
%ebp
• •
• •
• Offset relative •
to new %ebp
&zip2 12 yp
&zip1 8 xp
Rtn adr %esp 4 Rtn adr
Old %ebp %ebp
Old %ebx %esp
movl 12(%ebp),%ecx # get yp
movl 8(%ebp),%edx # get xp
. . .
Linux Stack Frame
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
Observation: Saved and restored
popl %ebp
ret 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 %ebp %ebp
%esp
Old %ebx %esp
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
Linux Stack Frame
University of Washington
swap Finish #3
swap’s Stack Resulting Stack
%ebp
• •
• •
• •
yp yp
xp xp
Rtn adr Rtn adr %esp
Old %ebp %ebp
Old %ebx %esp
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
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
Linux Stack Frame
University of Washington
Disassembled swap
080483a4 <swap>:
80483a4: 55 push %ebp
80483a5: 89 e5 mov %esp,%ebp
80483a7: 53 push %ebx
80483a8: 8b 55 08 mov 0x8(%ebp),%edx
80483ab: 8b 4d 0c mov 0xc(%ebp),%ecx
80483ae: 8b 1a mov (%edx),%ebx
80483b0: 8b 01 mov (%ecx),%eax
80483b2: 89 02 mov %eax,(%edx)
80483b4: 89 19 mov %ebx,(%ecx)
80483b6: 5b pop %ebx mov %ebp,%esp
80483b7: c9 leave pop %ebp
80483b8: c3 ret
Calling Code
8048409: e8 96 ff ff ff call 80483a4 <swap>
804840e: 8b 45 f8 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
Observation
movl -4(%ebp),%ebx Saved & restored register %ebx
movl %ebp,%esp Didn’t do so for %eax, %ecx, or %edx
popl %ebp
ret
Linux Stack Frame