View
46
Download
0
Category
Tags:
Preview:
DESCRIPTION
Procedure Call. Procedure/Function Implementation. Invoke callee: call (new instructions) Return to caller: ret (new instructions) Passing data: stack , register Registers: calling convention Local variable: stack. Local Variable. Why not store local variables in registers ? - PowerPoint PPT Presentation
Citation preview
1
Procedure Call
2
Procedure/Function Implementation
Invoke callee: call (new instructions)
Return to caller: ret (new instructions)
Passing data: stack, register
Registers: calling convention
? Local variable: stack
3
Local Variable
• Why not store local variables in registers ?
– No enough registers
– Array and structures (e.g., a[2])
– Need address (e.g., &a)
Old %ebpOld %ebp
Local Local variablevariable
Saved regsSaved regs
4
Local Variable
• Allocation
– Below saved regs or old %ebp
– move/sub %esp, (e.g., subl $4, %esp)
• De-allocation
– move/add %esp, (e.g., addl $4, %esp)
• Usage
– Relative to %esp/%ebp, (e.g., movl %eax, 8(%esp))
CalleeFrame
%ebp
%esp
retaddrretaddr
5
Put it TogetherCallerFrame
%ebp
%esp
caller-save caller-save registersregisters
6
Put it Together
1. Save caller-save registers
(%eax, %edx, %ecx)
CallerFrame
%ebp
%esp
argumentsarguments
(n~1)(n~1)
caller-save caller-save registersregisters
7
Put it Together
1. Save caller-save registers
(%eax, %edx, %ecx)
2. Push actual arguments
from right to left
CallerFrame
%ebp
%esp
argumentsarguments
(n~1)(n~1)
caller-save caller-save registersregisters
8
Put it Together
1. Save caller-save registers
(%eax, %edx, %ecx)
2. Push actual arguments
from right to left
3. Call instruction
– Save return address
– Transfer control to callee
retaddrretaddr
CallerFrame
%ebp
%esp
argumentsarguments
(n~1)(n~1)
9
Put it Together
4. Save caller %ebpcaller-save caller-save registersregisters
old %ebpold %ebp
retaddrretaddr
CallerFrame
%ebp
%esp
argumentsarguments
(n~1)(n~1)
10
Put it Together
4. Save caller %ebp
5. Set callee %ebp
caller-save caller-save registersregisters
old %ebpold %ebp
retaddrretaddr
CallerFrame
%esp / %ebp
argumentsarguments
(n~1)(n~1)
11
Put it Together
4. Save caller %ebp
5. Set callee %ebp
6. Save callee-save registers
(%ebx, %edi, %esi)
caller-save caller-save registersregisters
old %ebpold %ebp
retaddrretaddr
CallerFrame
callee-save callee-save registersregisters
%ebp
%esp
argumentsarguments
(n~1)(n~1)
12
Put it Together
4. Save caller %ebp
5. Set callee %ebp
6. Save callee-save registers
(%ebx, %edi, %esi)
7. Allocate space for local
variable
caller-save caller-save registersregisters
old %ebpold %ebp
retaddrretaddr
CallerFrame
callee-save callee-save registersregisters
local local variablesvariables
%ebp
%esp
13
Put it Together
. . .
n-4. save return value in %eaxargumentsarguments
(n~1)(n~1)
caller-save caller-save registersregisters
old %ebpold %ebp
retaddrretaddr
CallerFrame
callee-save callee-save registersregisters
local local variablesvariables
%ebp
%esp
14
Put it Together
. . .
n-4. save return value in %eax
n-3. de-allocate local variable
argumentsarguments
(n~1)(n~1)
caller-save caller-save registersregisters
old %ebpold %ebp
retaddrretaddr
CallerFrame
callee-save callee-save registersregisters
local variables
%ebp
%esp
15
Put it Together
. . .
n-4. save return value in %eax
n-3. de-allocate local variable
n-2. Restore callee-save registers
argumentsarguments
(n~1)(n~1)
caller-save caller-save registersregisters
old %ebpold %ebp
retaddrretaddr
CallerFrame
callee-save registers
local variables
%ebp%esp /
16
Put it Together
. . .
n-4. save return value in %eax
n-3. de-allocate local variable
n-2. Restore callee-save registers
n-1. Restore caller %ebp
argumentsarguments
(n~1)(n~1)
caller-save caller-save registersregisters
old %ebp
retaddrretaddr
CallerFrame
callee-save registers
local variables
%ebp
%esp
17
Put it Together
. . .
n-4. save return value in %eax
n-3. de-allocate local variable
n-2. Restore callee-save registers
n-1. Restore caller %ebp
n. Ret instruction
– pop return address
– Transfer control to caller
argumentsarguments
(n~1)(n~1)
caller-save caller-save registersregisters
old %ebp
retaddr
CallerFrame
callee-save registers
local variables
%ebp
%esp
18
Example
1 int swap_add(int *xp, int *yp)
2 {
3 int x = *xp;
4 int y = *yp;
5
6 *xp = y;
7 *yp = x;
8 return x + y;
9 }
10
19
Example
11 int caller()12 {13 int arg1 = 534;14 int arg2 = 1057;15 int sum = swap_add(&arg1, &arg2);16 int diff = arg1 - arg2;1718 return sum * diff;19 }
20
Example
0 Saved %ebp
-4 arg2(1057)
-8 arg1(534)
-12
Stack frame for callerBefore
int sum = swap_add(&arg1, &arg2);%ebp
%esp
21
Parameter Passing
0 Saved %ebp
-4 arg2(1057)
-8 arg1(534)
-12 &arg2
Stack frame for caller1 leal -4(%ebp),%eax
Compute &arg2
2 pushl %eax
Push &arg2
%ebp
%esp
22
Parameter Passing
0 Saved %ebp
-4 arg2(1057)
-8 arg1(534)
-12 &arg2
-16 &arg1
Stack frame for caller1 leal -4(%ebp),%eax
Compute &arg2
2 pushl %eax
Push &arg2
3 leal -8(%ebp),%eax
Compute &arg1
4 pushl %eax
Push &arg1
%ebp
%esp
23
Call Instruction
0 Saved %ebp
-4 arg2(1057)
-8 arg1(534)
-12 &arg2
-16 &arg1
-20 Return Addr
Stack frame for caller1 leal -4(%ebp),%eax
Compute &arg2
2 pushl %eax
Push &arg2
3 leal -8(%ebp),%eax
Compute &arg1
4 pushl %eax
Push &arg1
5 call swap_add
Call the swap_add function
%ebp
%esp
24
Setup code in swap_add
0 Saved %ebp
-4 arg2(1057)
-8 arg1(534)
-12 yp(&arg2)
-16 xp(&arg1)
-20 Return Addr
-24 Saved %ebp
Stack frame for callerswap_add:
1 pushl %ebp Save old %ebp
%ebp
%esp
25
Setup code in swap_add
24 Saved %ebp
20 arg2(1057)
16 arg1(534)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
Stack frame for callerswap_add:
1 pushl %ebp Save old %ebp
2 movl %esp,%ebp
Set %ebp as frame pointer
%ebp
%esp
Stack frame for swap_add
26
Setup code in swap_add
24 Saved %ebp
20 arg2(1057)
16 arg1(534)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
-4 Saved %ebx
Stack frame for callerswap_add:
1 pushl %ebp Save old %ebp
2 movl %esp,%ebp
Set %ebp as frame pointer
3 pushl %ebx
Save %ebx
%esp
%ebp
Stack frame for swap_add
27
Body code in swap_add
24 Saved %ebp
20 arg2(1057)
16 arg1(534)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
-4 Saved %ebx
Stack frame for caller
%esp
%ebp
Stack frame for swap_add
xp(=&arg1=%ebp+16)%edx
5 movl 8(%ebp),%edx Get xp
28
Body code in swap_add
24 Saved %ebp
20 arg2(1057)
16 arg1(534)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
-4 Saved %ebx
Stack frame for caller
%esp
%ebp
Stack frame for swap_add
xp(=&arg1=%ebp+16)%edx
yp(=&arg2=%ebp+20)%ecx
5 movl 8(%ebp),%edx Get xp
6 movl 12(%ebp),%ecx Get yp
29
Body code in swap_add
24 Saved %ebp
20 arg2(1057)
16 arg1(534)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
-4 Saved %ebx
Stack frame for caller5 movl 8(%ebp),%edx Get xp
6 movl 12(%ebp),%ecx Get yp
7 movl (%edx),%ebx Get x
8 movl (%ecx),%eax Get y
%esp
%ebp
Stack frame for swap_add
xp(=&arg1=%ebp+16)%edx
yp(=&arg2=%ebp+20)%ecx
534 %ebx
1057 %eax
30
Body code in swap_add
24 Saved %ebp
20 arg2(1057)
16 arg1(1057)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
-4 Saved %ebx
Stack frame for caller9 movl %eax, (%edx) Store y at *xp
%esp
%ebp
Stack frame for swap_add
xp(=&arg1=%ebp+16)%edx
yp(=&arg2=%ebp+20)%ecx
534 %ebx
1057 %eax
31
Body code in swap_add
24 Saved %ebp
20 arg2(534)
16 arg1(1057)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
-4 Saved %ebx
Stack frame for caller9 movl %eax, (%edx) Store y at *xp
10 movl %ebx, (%ecx) Store x at
*yp
%esp
%ebp
Stack frame for swap_add
xp(=&arg1=%ebp+16)%edx
yp(=&arg2=%ebp+20)%ecx
534 %ebx
1057 %eax
32
Body code in swap_add
24 Saved %ebp
20 arg2(534)
16 arg1(1057)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
-4 Saved %ebx
Stack frame for caller9 movl %eax, (%edx) Store y at *xp
10 movl %ebx, (%ecx) Store x at
*yp
11 addl %ebx,%eax Set return value = x+y
%esp
%ebp
Stack frame for swap_add
xp(=&arg1=%ebp+16)%edx
yp(=&arg2=%ebp+20)%ecx
534 %ebx
1591 %eax
33
Finishing code in swap_add
24 Saved %ebp
20 arg2(534)
16 arg1(1057)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
-4 Saved %ebx
Stack frame for caller12 popl %ebx Restore %ebx
%esp
%ebp
Stack frame for swap_add
xp(=&arg1=%ebp+16)%edx
yp(=&arg2=%ebp+20)%ecx
original value %ebx
1591 %eax
34
Finishing code in swap_add
24 Saved %ebp
20 arg2(534)
16 arg1(1057)
12 yp(&arg2)
8 xp(&arg1)
4 Return Addr
0 Saved %ebp
-4 Saved %ebx
Stack frame for caller12 popl %ebx Restore %ebx
13 movl %ebp, %esp Restore %esp
%esp
%ebp
Stack frame for swap_add
xp(=&arg1=%ebp+16)%edx
yp(=&arg2=%ebp+20)%ecx
original value %ebx
1591 %eax
35
Finishing code in swap_add
0 Saved %ebp
-4 arg2(534)
-8 arg1(1057)
-12 yp(&arg2)
-16 xp(&arg1)
-20 Return Addr
Saved %ebp
Saved %ebx
Stack frame for caller12 popl %ebx Restore %ebx
13 movl %ebp, %esp Restore %esp
14 popl %ebp Restore %ebp
%ebp
xp(=&arg1=%ebp+16)%edx
yp(=&arg2=%ebp+20)%ecx
original value %ebx
1591 %eax
%esp
36
Finishing code in swap_add
0 Saved %ebp
-4 arg2(534)
-8 arg1(1057)
-12 yp(&arg2)
-16 xp(&arg1)
-20 Return Addr
Saved %ebp
Saved %ebx
Stack frame for caller12 popl %ebx Restore %ebx
13 movl %ebp, %esp Restore %esp
14 popl %ebp Restore %ebp
15 ret Return to caller
• Call by value
%ebp
xp(=&arg1=%ebp+16)%edx
yp(=&arg2=%ebp+20)%ecx
original value %ebx
1591 %eax
%esp
37
Recursion Example
1 int fib_rec(int n)
2 {
3 int prev_val, val;
4
5 if (n <= 2)
6 return 1;
7 prev_val = fib_rec(n-2);
8 val = fib_rec(n-1);
9 return prev_val + val;
10 }
38
Setup code
1 fib_rec:
2 pushl %ebp Save old %ebp
3 movl %esp,%ebp Set %ebp as frame pointer
4 subl $16,%esp Allocate 16 bytes on stack
5 pushl %esi Save %esi (offset -20)
6 pushl %ebx Save %ebx (offset -24)
39
Recursion
.
.
.
.
+8 n
+4 Return Addr
0 Saved %ebp
Unused-20 Saved %esi
-24 Saved %ebx
Stack frame
%ebp
%esp
40
Body code
7 movl 8(%ebp),%ebx Get n
8 cmpl $2,%ebx Compare n:2
9 jle .L24 if <=, goto terminate
10 addl $-12,%esp Allocate 12 bytes on
stack
11 leal -2(%ebx),%eax Compute n-2
12pushl %eax Push as argument
13call fib_rec Call fib_rec(n-2)
41
Recursion
.
.
.
.
+8 n
+4 Return Addr
0 Saved %ebp
Unused-20 Saved %esi
-24 Saved %ebx
Unused -40 n-2
Stack frame
%ebp
%esp
42
Body code
14 movl %eax,%esi Store result in %esi
15 addl $-12,%esp Allocate 12 bytes to
stack
16 leal -1(%ebx),%eax Compute n-1
17 pushl %eax Push as argument
18 call fib_rec Call fib_rec(n-1)
19 addl %esi,%eax Compute val+nval
20 jmp .L25 Go to done
43
%ebp
%esp
.
.
.
.
+8 n
+4 Return Addr
0 Saved %ebp
Unused-20 Saved %esi
-24 Saved %ebx
Unused -40 n-2
Unused
-56 n-1
Stack frame
44
Terminal condition
21 .L24: terminate:
22 movl $1,%eax Return value 1
45
Finishing code
23 .L25: done:
24 leal -24(%ebp),%esp Set stack to offset -24
25 popl %ebx Restore %ebx
26 popl %esi Restore %esi
27 movl %ebp,%esp Restore stack pointer
28 popl %ebp Restore %ebp
29 ret Return
46
Permutation
1. #include <stdio.h>
2. void permute(int a[], int n, int k)3. {4. int i;5. if (k == 0) {6. for ( i=0; i<n; i++)7. printf("%d", a[i]);8. printf("\n");9. }
47
Permutation
10. for ( i=0; i<=k; i++) {11. int tempi = a[i], tempk = a[k];12. a[i] = tempk ; a[k] = tempi;13. permute(a,n,k-1);14. a[i] = tempi; a[k] = tempk;15. }16. }
48
Permutation
.file "permute.c"
.section .rdata,"dr"
LC0:
.ascii "%d\0"
.text
.globl _permute
.def _permute; .scl 2; .type 32; .endef
49
Permutation
_permute:
pushl %ebp
movl %esp, %ebp
subl $40, %esp
cmpl $0, 16(%ebp) # k == 0 ?
jne L2
movl $0, -12(%ebp) # i = 0
jmp L3
50
Permutation
L4:
movl -12(%ebp), %eax # i
sall $2, %eax # 4*i
addl 8(%ebp), %eax # a+4*i
movl (%eax), %eax # a[i]
movl %eax, 4(%esp) # pushl a[i]
movl $LC0, (%esp) # pushl “%d\n”
call _printf
addl $1, -12(%ebp) # i = i + 1
51
Permutation
L3:
movl -12(%ebp), %eax
cmpl 12(%ebp), %eax # i ? n
jl L4
movl $10, (%esp) # \n
call _putchar
L2:
movl $0, -12(%ebp) # i = 0
jmp L5
52
Permutation
L6:movl -12(%ebp), %eaxsall $2, %eaxaddl 8(%ebp), %eaxmovl (%eax), %eaxmovl %eax, -8(%ebp) # tempi = a[i]movl 16(%ebp), %eaxsall $2, %eaxaddl 8(%ebp), %eaxmovl (%eax), %eaxmovl %eax, -4(%ebp) # tempk = a[k]
53
Permutation
movl -12(%ebp), %eaxsall $2, %eaxmovl %eax, %edxaddl 8(%ebp), %edxmovl -4(%ebp), %eaxmovl %eax, (%edx) # a[i] = tempkmovl 16(%ebp), %eaxsall $2, %eaxmovl %eax, %edxaddl 8(%ebp), %edxmovl -8(%ebp), %eaxmovl %eax, (%edx) # a[k] = tempi
54
Permutation
movl 16(%ebp), %eax
subl $1, %eax
movl %eax, 8(%esp) # pushl k-1
movl 12(%ebp), %eax
movl %eax, 4(%esp) # pushl n
movl 8(%ebp), %eax
movl %eax, (%esp) # pushl a
call _permute
55
Permutation
movl -12(%ebp), %eaxsall $2, %eaxmovl %eax, %edxaddl 8(%ebp), %edxmovl -8(%ebp), %eaxmovl %eax, (%edx) # a[i] = tempimovl 16(%ebp), %eaxsall $2, %eaxmovl %eax, %edxaddl 8(%ebp), %edxmovl -4(%ebp), %eaxmovl %eax, (%edx) # a[k] = tempk
56
Permutation
addl $1, -12(%ebp) # i = i + 1
L5:
movl -12(%ebp), %eax
cmpl 16(%ebp), %eax
jle L6
leave
ret
57
Permutation
int a[]={1,2,3,4};
void main()
{
permute(a, sizeof(a)/sizeof(a[0]), sizeof(a)/sizeof(a[0])-1);
}
58
Permutation
.globl _a
.data
.align 4
_a:
.long 1
.long 2
.long 3
.long 4
59
Permutation
.text
_main:
………
movl $3, 8(%esp)
movl $4, 4(%esp)
movl $_a, (%esp)
call _permute
………
ret
Recommended