Stack and Procedures
Download
Report
Transcript Stack and Procedures
Devoir surveillé
Vendredi 22 février 14h-15h20
Amphi Turing
Programme
Tous les sujets traités en TD
jusqu’au mercredi 20 inclus
Sans document
Adaptation par J.Bétréma
Machine-Level Programming :
Stack and Procedures
Topics
IA32 stack discipline
Procedure calls
Register saving conventions
Randal E. Bryant & David R. O'Hallaron
Carnegie Mellon University
http://csapp.cs.cmu.edu
class07.ppt
Y86 Program Stack
Code
Increasing
Addresses
Region of memory holding
program data
Used in Y86 (and IA32) for
supporting procedure calls
Stack top indicated by %esp
(Stack Pointer)
Address of top stack element
Stack “Top”
%esp
Stack
“Bottom”
–3–
Stack grows toward lower
addresses
Top element is at highest
address in the stack
When pushing, must first
decrement stack pointer
When popping, increment stack
pointer
Pile et procédures
Stack Operations
pushl rA
Decrement %esp by 4
Store word from rA to memory at %esp
Like IA32
popl rA
–4–
a 0 rA 8
b 0 rA 8
Read word from memory at %esp
Save in rA
Increment %esp by 4
Like IA32
Pile et procédures
IA32 Stack Pushing
Pushing
pushl Src
Fetch operand at Src
Decrement %esp by 4
Stack
Pointer
%esp
-4
%eax
Write operand at address
given by %esp
Y86
–5–
Src = registre
Exemple : pushl %eax
empile le contenu du registre %eax
Pile et procédures
IA32 Stack Popping
Popping
popl Dest
Read operand at address
given by %esp
Increment %esp by 4
Write to Dest
Stack
Pointer + 4
%esp
Y86
–6–
Dest = registre
Exemple : popl %edx
dépile dans %edx le mot
en sommet de pile
Pile et procédures
Stack Operation Examples
pushl %eax
0x108
123
popl %edx
0x104
213
0x104
213
0x108
123
0x108
123
0x10c
0x10c
0x10c
0x110
0x110
0x110
%eax
213
%eax
213
%eax
213
%edx
555
%edx
555
%edx
555
213
%esp
0x108
%esp
0x104
0x108
%esp
0x104
0x108
–7–
Pile et procédures
Call Chain Example
Code Structure
f(…)
{
•
•
g();
•
•
}
–8–
Call Chain
Vocabulaire : fonction C
= procédure = subroutine
g(…)
{
• • •
h();
• • •
h();
• • •
}
f
g
Profondeur
de l’arbre
des appels
non bornée
h
h
...
...
Pile et procédures
Adresse de retour
Procédure appelée
Procédure appelante
f(…)
{
•
•
g();
•
•
}
jmp g
jmp ???
g(…)
{
• • •
h();
• • •
h();
• • •
}
Solution : la procédure appelante sauve
l’adresse de retour avant l’appel.
–9–
La procédure
appelée ignore
l’adresse de
retour, car elle
ignore qui l’a
appelée.
Où ? sur la pile !
Pile et procédures
Procedure Control Flow
Use stack to support procedure call and return
Procedure call:
call label
Push return address on stack; Jump to label
Return address value
Address of instruction beyond call
Example from disassembly
804854e: e8 3d 06 00 00
8048553: 8b 45 0c
call
mov
8048b90
0xc(%ebp),%eax
Return address = 0x8048553
Procedure return:
– 10 –
ret
Pop address from stack; Jump to address
Pile et procédures
Subroutine Call and Return
call Dest
ret
– 11 –
8 0
Dest
Push address of next instruction onto stack
Start executing instructions at Dest
Like IA32
9 0
Pop value from stack
Use as address for next instruction
Like IA32
Pile et procédures
Stack-Based Languages
Languages that Support Recursion
Code must be “Reentrant”
Multiple simultaneous instantiations of single procedure
Need some place to store state of each instantiation
Arguments
Local variables
Return pointer
Stack Discipline
State for given procedure needed for limited time
From when called to when return
Callee returns before caller does
Stack Allocated in Frames
– 12 –
state for single procedure instantiation
Pile et procédures
Stack Frames
Contents
Local variables
Return information
Temporary space
f
g
h
Management
Space allocated when enter
procedure
“Set-up” code
Deallocated when return
proc
“Finish” code
Pointers
– 13 –
Stack pointer %esp
indicates stack top
Frame pointer %ebp indicates
start of current frame
Stack
“Top”
Stack
Pointer
%esp
%ebp
Frame
Pointer
Pile et procédures
Stack Operation
f(…)
{
•
•
g();
•
•
}
Call Chain
f
Stack
Pointer
%esp
f
%ebp
Frame
Pointer
– 14 –
•
•
•
Pile et procédures
Stack Operation
g(…)
{
• • •
h();
• • •
h();
• • •
}
Call Chain
f
g
Stack
Pointer
%esp
g
%ebp
Frame
Pointer
f
•
•
•
– 15 –
Pile et procédures
Stack Operation
h(…)
{
•
•
•
•
}
Call Chain
f
g
h
Stack
Pointer
%esp
h
%ebp
Frame
Pointer
g
f
•
•
•
– 16 –
Pile et procédures
Stack Operation
g(…)
{
• • •
h();
• • •
h();
• • •
}
Call Chain
f
g
Stack
Pointer
%esp
g
h
%ebp
Frame
Pointer
f
•
•
•
– 17 –
Pile et procédures
Stack Operation
h(…)
{
•
•
•
•
}
Call Chain
Stack
Pointer
%esp
f
h
g
h
h
%ebp
Frame
Pointer
g
f
•
•
•
– 18 –
Pile et procédures
Stack Operation
g(…)
{
• • •
h();
• • •
h();
• • •
}
Call Chain
f
Stack
Pointer
%esp
g
h
g
h
%ebp
Frame
Pointer
f
•
•
•
– 19 –
Pile et procédures
Stack Operation
f(…)
{
•
•
g();
•
•
}
Call Chain
f
g
h
h
Stack
Pointer
%esp
f
%ebp
Frame
Pointer
– 20 –
•
•
•
Pile et procédures
IA32/Linux Stack Frame
Current Stack Frame (“Top”
to Bottom)
Stack Pointer
(%esp)
Parameters for function
about to call
Saved
Registers
+
Local
Variables
“Argument build”
Local variables
If can’t keep in registers
Saved register context
Old frame pointer
Frame Pointer
(%ebp)
Caller Stack Frame
Return address
Pushed by call instruction
– 21 –
Argument
Build
Old %ebp
Return Addr
Arguments
Caller
Frame
Arguments for this call
Pile et procédures
Example: swap
Calling swap from call_swap
int zip1 = 15213;
int zip2 = 91125;
void call_swap()
{ ...
swap(&zip1, &zip2);
...
}
call_swap:
• • •
pushl $zip2
pushl $zip1
call swap
• • •
%esp
# Global Var
# Global Var
Rtn adr
&zip1
void swap(int *xp, int *yp)
{
int t0 = *xp;
int t1 = *yp;
*xp = t1;
*yp = t0;
}
– 22 –
Resulting
Stack
&zip2
•
•
•
Pile et procédures
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
Set
Up
12(%ebp),%ecx
8(%ebp),%edx
(%ecx),%eax
(%edx),%ebx
%eax,(%edx)
%ebx,(%ecx)
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
– 23 –
Body
Finish
Pile et procédures
swap Setup
%ebp
%esp
Old %ebx
%esp
%ebp
Old %ebp
%esp
Rtn adr
&zip1
swap:
pushl %ebp
movl %esp,%ebp
pushl %ebx
&zip2
•
•
•
%ebp
– 24 –
Pile et procédures
Effect of swap Setup
movl 12(%ebp),%ecx # get yp
movl 8(%ebp),%edx # get xp
. . .
Entering
Stack
%esp
Rtn adr
&zip1
&zip2
•
•
•
Resulting
Stack
Body
%esp
Offset
(relative to %ebp)
Old %ebx
0
Old %ebp
4
Rtn adr
8
xp
12
yp
%ebp
•
•
•
%ebp
– 25 –
Pile et procédures
swap Finish
%esp
%esp
Old
%ebx
%ebx
%ebp
Old
%ebp
%ebp
%esp
Rtn adr
%esp
xp
Restores %ebx
movl -4(%ebp),%ebx
movl %ebp,%esp
popl %ebp
ret
yp
•
•
•
%ebp
– 26 –
Observation
Saved & restored
register %ebx
Didn’t do so for
%eax, %ecx, or %edx
Pile et procédures
Register Saving Conventions
When procedure f calls g:
f is the caller, g is the callee
Can Register be Used for Temporary Storage?
f:
g:
• • •
movl $15213, %edx
call g
addl %edx, %eax
• • •
ret
– 27 –
• • •
movl 8(%ebp), %edx
addl $91125, %edx
• • •
ret
Contents of register %edx overwritten by g
Pile et procédures
Register Saving Conventions
When procedure f calls g:
f is the caller, g is the callee
Can Register be Used for Temporary Storage?
Conventions
“Caller Save”
Caller saves temporary in its frame before calling
“Callee Save”
Callee saves temporary in its frame before using
– 28 –
Pile et procédures
IA32/Linux Register Usage
Integer Registers
%ebp, %esp
Three managed as
callee-save
%ebx, %esi, %edi
Old values saved on
stack prior to using
– 29 –
Caller-Save
Temporaries
Register %eax also
stores returned value
%ecx
%edx
%ebx
Callee-Save
Temporaries
%esi
%edi
Three managed as
caller-save
%eax, %ecx, %edx
Do what you please,
but expect any callee
to do so, as well
%eax
Two have special uses
%ebp
Special
%esp
Pile et procédures
Procédures récursives
Le protocole précédent ne limite pas la profondeur
de l’arbre des appels.
Pièces bien placées sur l’échiquier = position solide.
Prêt à parer une attaque inattendue :
Procédure récursive = procédure qui s’appelle elle-même
Procédure appelante (caller) = procédure appelée (callee)
– 30 –
Pile et procédures
Informatique théorique
Un automate à états finis ne peut pas gérer
correctement les appels de procédures :
Le langage des mots de la forme an bn n’est pas rationnel
Idem pour le langage des parenthèses mots de la forme
()(()())=abaababb
a = appel (call) b = retour (return)
Pour parcourir un arbre il faut un automate à pile !
– 31 –
Pile et procédures
rfact:
pushl %ebp
movl %esp,%ebp
int rfact (int x)
pushl %ebx
lit l’argument
{
movl 8(%ebp),%ebx
int rval;
cmpl $1,%ebx
if (x <= 1)
jle .L78
return 1;
calcule x-1
leal -1(%ebx),%eax
rval = rfact (x-1);
pushl %eax
return rval * x;
call rfact
}
imull %ebx,%eax
jmp .L79
empile l’argument
.align 4
avant l’appel récursif
.L78:
Registers
movl $1,%eax
%eax used without first
.L79:
movl -4(%ebp),%ebx
saving
movl %ebp,%esp
%ebx used, but save at
popl %ebp
beginning & restore at end
ret
Recursive Factorial
– 32 –
Pile et procédures
Summary
The Stack Makes Procedures Work
Private storage for each instance of procedure call
Instantiations don’t clobber each other
Addressing of locals + arguments can be relative to stack
positions
Can be managed by stack discipline
Procedures return in inverse order of calls
IA32 Procedures Combination of Instructions +
Conventions
Call / Ret instructions
Register usage conventions
Caller / Callee save
%ebp and %esp
– 33 –
Stack frame organization conventions
Pile et procédures