06 Procedures
06 Procedures
Computer
system:
Memory Layout
2N-1
local variables;
Stack procedure context
Instructions
0
Autumn 2013 Procedures and Stacks 3
University of Washington
segmentation faults?
Memory Layout
Stack “Top”
Autumn 2013 Procedures and Stacks 5
University of Washington
Increasing
Addresses
Stack Grows
Down
Stack Pointer: %esp
Stack “Top”
Stack Grows
Down
-4
Stack Pointer: %esp
Stack “Top”
Autumn 2013 Procedures and Stacks 7
University of Washington
Increasing
Addresses
Stack Grows
Down
Stack Pointer: %esp
Stack “Top”
Autumn 2013 Procedures and Stacks 8
University of Washington
Stack Grows
Stack Pointer: %esp Down
+4
Stack “Top”
Stack Grows
Stack Pointer: %esp Down
+4
Stack “Top”
Those bits are still there;
we’re just not using them.
Autumn 2013 Procedures and Stacks 10
University of Washington
call 8048b90
0x110
0x10c
0x108 123
%esp 0x108
%eip 0x804854e
call 8048b90
0x110 0x110
0x10c 0x10c
0x108 123 0x108 123
0x104 0x8048553
call 8048b90
0x110 0x110
0x10c 0x10c
0x108 123 0x108 123
0x104 0x8048553
relative address
%eip 0x804854e %eip 0x8048553
just like jumps…
+ 0x000063d (chosen by compiler;
there’s also an absolute call)
0x8048b90
%eip: program counter
Autumn 2013 Procedures and Stacks 17
University of Washington
ret
0x110
0x10c
0x108 123
0x104 0x8048553
%esp 0x104
%eip 0x8048591
ret
0x110 0x110
0x10c 0x10c
0x108 123 0x108 123
0x104 0x8048553 0x8048553
ret
0x110 0x110
0x10c 0x10c
0x108 123 0x108 123
0x104 0x8048553 0x8048553
ret
0x110 0x110
0x10c 0x10c
0x108 123 0x108 123
0x104 0x8048553 0x8048553
Stack-Based Languages
¢ Languages that support recursion
§ e.g., C, Java, most modern languages
§ Code must be re-entrant
Multiple simultaneous instantiations of single procedure
§
§ Need some place to store state of each instantiation
§ Arguments
§ Local variables
§ Return pointer
¢ Stack discipline
§ State for a given procedure needed for a limited time
§ Starting from when it is called to when it returns
§ Callee always returns before caller does
¢ Stack allocated in frames
§ State for a single procedure instantiation
Stack Frames
Previous
¢ Contents Frame
§ Local variables
§ Function arguments Frame Pointer: %ebp
§ Return information Frame
§ Temporary space for
current
proc
Stack Pointer: %esp
¢ Management
§ Space allocated when procedure is entered Stack “Top”
“Set-up” code
§
§ Space deallocated upon return
§ “Finish” code
Stack
Example
yoo(…) yoo
%ebp
{
• yoo
who
• %esp
who();
• amI amI
•
}
amI
amI
Stack
Example
who(…) yoo
{
• • • yoo
who
amI();
• • • %ebp
amI(); amI amI who
• • •
%esp
}
amI
amI
Stack
Example
amI(…) yoo
{
• yoo
who
•
amI();
• amI amI who
•
} %ebp
amI
amI
%esp
amI
Stack
Example
amI(…) yoo
{
• yoo
who
•
amI();
• amI amI who
•
}
amI
amI
amI %ebp
amI
%esp
Stack
Example
amI(…) yoo
{
• yoo
who
•
amI();
• amI amI who
•
}
amI
amI
amI
amI
%ebp
amI
%esp
Stack
Example
amI(…) yoo
{
• yoo
who
•
amI();
• amI amI who
•
}
amI
amI
amI %ebp
amI
%esp
Stack
Example
amI(…) yoo
{
• yoo
who
•
amI();
• amI amI who
•
} %ebp
amI
amI
%esp
amI
Stack
Example
who(…) yoo
{
• • • yoo
who
amI();
• • • %ebp
amI(); amI amI who
• • •
%esp
}
amI
amI
Stack
Example
amI(…) yoo
{
• yoo
who
•
•
• amI amI who
•
} %ebp
amI
amI
%esp
amI
Stack
Example
who(…) yoo
{
• • • yoo
who
amI();
• • • %ebp
amI(); amI amI who
• • •
%esp
}
amI
amI
Stack
Example
yoo(…) yoo
%ebp
{
• yoo
who
• %esp
who();
• amI amI
•
}
amI
amI
Revisiting swap
int zip1 = 15213;
int zip2 = 98195;
void call_swap()
{
swap(&zip1, &zip2);
}
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); • • •
}
not Global War!
we know the address
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
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
swap Setup #1
Entering Stack Resulting Stack?
%ebp
•
•
•
&zip2
&zip1
Rtn adr %esp
swap:
pushl %ebp
movl %esp,%ebp Set
pushl %ebx Up
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 Set
pushl %ebx Up
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 Set
pushl %ebx Up
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 Set
pushl %ebx Up
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
swap Finish #1
Finishing Stack Resulting Stack?
•
•
•
yp
xp
Rtn adr
Old %ebp %ebp
Old %ebx %esp
movl -4(%ebp),%ebx
movl %ebp,%esp
Finish
popl %ebp
ret
Autumn 2013 Procedures and Stacks 46
University of Washington
swap Finish #1
Finishing 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
Finish Observation: Saved and restored
popl %ebp
ret register %ebx
Autumn 2013 Procedures and Stacks 47
University of Washington
swap Finish #2
Finishing 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
Finish
popl %ebp
ret
Autumn 2013 Procedures and Stacks 48
University of Washington
swap Finish #3
Finishing 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
Finish
popl %ebp
ret
Autumn 2013 Procedures and Stacks 49
University of Washington
swap Finish #4
Finishing Stack Resulting Stack
%ebp
• •
• •
• •
yp yp
xp xp %esp
Rtn adr
Old %ebp %ebp
Old %ebx %esp
movl -4(%ebp),%ebx
movl %ebp,%esp
Finish
popl %ebp
ret
Autumn 2013 Procedures and Stacks 50
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
swap Finish #4
Finishing 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
Finish § but not %eax, %ecx, or %edx
popl %ebp
ret
Autumn 2013 Procedures and Stacks 52
University of Washington
8 x
4 Rtn adr %esp
Initial part of sfact
0 Old %ebp %ebp
_sfact:
pushl %ebp # Save %ebp -4 val = 1 %esp
movl %esp,%ebp # Set %ebp -8 Temp.
subl $16,%esp # Add 16 bytes
-12 Space
Unused
movl 8(%ebp),%edx # edx = x
movl $1,-4(%ebp) # val = 1 -16 %esp
Passing Pointer
¢ Variable val must be stored on stack
int sfact(int x)
§ Because: Need to create pointer to it
{
int val = 1; ¢ Compute pointer as -4(%ebp)
s_helper(x, &val); ¢ Push on stack as second argument
return val;
}
Stack at time of call: 8 x
4 Rtn adr
0 Old %ebp %ebp
Calling s_helper from sfact -4 val
val=x!
= 1
leal -4(%ebp),%eax # Compute &val -8
pushl %eax # Push on stack -12 Unused
pushl %edx # Push x
call s_helper # call -16
%esp
movl -4(%ebp),%eax # Return val &val
• • • # Finish
x
IA 32 Procedure Summary
¢ Important points:
§ IA32 procedures are a combination of instructions
and conventions Caller
§ Conventions prevent functions from Frame
disrupting each other Arguments
§ Stack is the right data structure for procedure
Return Addr
call / return
%ebp Old %ebp
§ If P calls Q, then Q returns before P
Saved
¢ Recursion handled by normal calling Registers
conventions +
§ Can safely store values in local stack frame and in Local
callee-saved registers Variables
§ Put function arguments at top of stack
Argument
§ Result returned in %eax Build
%esp
Autumn 2013 Procedures and Stacks 62
University of Washington
Instructions
0
Autumn 2013 Procedures and Stacks 67
University of Washington
Example
long int call_proc() call_proc:
{ subq $32,%rsp
long x1 = 1; movq $1,16(%rsp)
int x2 = 2; movl $2,24(%rsp)
short x3 = 3; movw $3,28(%rsp)
char x4 = 4; movb $4,31(%rsp)
proc(x1, &x1, x2, &x2, • • •
x3, &x3, x4, &x4);
return (x1+x2)*(x3-x4);
}
Example
long int call_proc() call_proc:
{ subq $32,%rsp
long x1 = 1; movq $1,16(%rsp)
int x2 = 2; movl $2,24(%rsp)
short x3 = 3; movw $3,28(%rsp)
char x4 = 4; movb $4,31(%rsp)
proc(x1, &x1, x2, &x2, • • •
x3, &x3, x4, &x4);
return (x1+x2)*(x3-x4);
}
%rsp
Example
long int call_proc() call_proc:
{ • • •
long x1 = 1; leaq 24(%rsp),%rcx
int x2 = 2; leaq 16(%rsp),%rsi
short x3 = 3; leaq 31(%rsp),%rax
char x4 = 4; movq %rax,8(%rsp)
proc(x1, &x1, x2, &x2, movl $4,(%rsp)
x3, &x3, x4, &x4); leaq 28(%rsp),%r9
return (x1+x2)*(x3-x4); movl $3,%r8d
} movl $2,%edx
movq $1,%rdi
Return address to caller of call_proc call proc
x4 x3 x2 • • •
Example
long int call_proc() call_proc:
{ • • •
long x1 = 1; leaq 24(%rsp),%rcx
int x2 = 2; leaq 16(%rsp),%rsi
short x3 = 3; leaq 31(%rsp),%rax
char x4 = 4; movq %rax,8(%rsp)
proc(x1, &x1, x2, &x2, movl $4,(%rsp)
x3, &x3, x4, &x4); leaq 28(%rsp),%r9
return (x1+x2)*(x3-x4); movl $3,%r8d note
} movl $2,%edx sizes
movq $1,%rdi
Return address to caller of call_proc call proc
x4 x3 x2 • • •
Example
long int call_proc() call_proc:
{ • • •
long x1 = 1; leaq 24(%rsp),%rcx
int x2 = 2; leaq 16(%rsp),%rsi
short x3 = 3; leaq 31(%rsp),%rax
char x4 = 4; movq %rax,8(%rsp)
proc(x1, &x1, x2, &x2, movl $4,(%rsp)
x3, &x3, x4, &x4); leaq 28(%rsp),%r9
return (x1+x2)*(x3-x4); movl $3,%r8d
} movl $2,%edx
movq $1,%rdi
Return address to caller of call_proc call proc
x4 x3 x2 • • •
x1
Arg 8
Arg 7
Return address to line after call to proc %rsp
Autumn 2013 Procedures and Stacks 73
University of Washington
Example
long int call_proc() call_proc:
{ • • •
long x1 = 1; movswl 28(%rsp),%eax
int x2 = 2; movsbl 31(%rsp),%edx
short x3 = 3; subl %edx,%eax
char x4 = 4; cltq
proc(x1, &x1, x2, &x2, movslq 24(%rsp),%rdx
x3, &x3, x4, &x4); addq 16(%rsp),%rdx
return (x1+x2)*(x3-x4); imulq %rdx,%rax
} addq $32,%rsp
ret
Return address to caller of call_proc %rsp