59
1 Procedure Call

Procedure Call

Embed Size (px)

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

Page 1: Procedure Call

1

Procedure Call

Page 2: 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

Page 3: Procedure Call

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)

Page 4: Procedure Call

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

Page 5: Procedure Call

5

Put it TogetherCallerFrame

%ebp

%esp

Page 6: Procedure Call

caller-save caller-save registersregisters

6

Put it Together

1. Save caller-save registers

(%eax, %edx, %ecx)

CallerFrame

%ebp

%esp

Page 7: Procedure Call

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

Page 8: Procedure Call

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

Page 9: Procedure Call

argumentsarguments

(n~1)(n~1)

9

Put it Together

4. Save caller %ebpcaller-save caller-save registersregisters

old %ebpold %ebp

retaddrretaddr

CallerFrame

%ebp

%esp

Page 10: Procedure Call

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

Page 11: Procedure Call

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

Page 12: Procedure Call

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

Page 13: Procedure Call

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

Page 14: Procedure Call

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

Page 15: Procedure Call

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 /

Page 16: Procedure Call

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

Page 17: Procedure Call

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

Page 18: Procedure Call

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

Page 19: Procedure Call

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 }

Page 20: Procedure Call

20

Example

0 Saved %ebp

-4 arg2(1057)

-8 arg1(534)

-12

Stack frame for callerBefore

int sum = swap_add(&arg1, &arg2);%ebp

%esp

Page 21: Procedure Call

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

Page 22: Procedure Call

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

Page 23: Procedure Call

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

Page 24: Procedure Call

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

Page 25: Procedure Call

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

Page 26: Procedure Call

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

Page 27: Procedure Call

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

Page 28: Procedure Call

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

Page 29: Procedure Call

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

Page 30: Procedure Call

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

Page 31: Procedure Call

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

Page 32: Procedure Call

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

Page 33: Procedure Call

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

Page 34: Procedure Call

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

Page 35: Procedure Call

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

Page 36: Procedure Call

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

Page 37: Procedure Call

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 }

Page 38: Procedure Call

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)

Page 39: Procedure Call

39

Recursion

.

.

.

.

+8 n

+4 Return Addr

0 Saved %ebp

Unused-20 Saved %esi

-24 Saved %ebx

Stack frame

%ebp

%esp

Page 40: Procedure Call

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)

Page 41: Procedure Call

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

Page 42: Procedure Call

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

Page 43: Procedure Call

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

Page 44: Procedure Call

44

Terminal condition

21 .L24: terminate:

22 movl $1,%eax Return value 1

Page 45: Procedure Call

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

Page 46: Procedure Call

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. }

Page 47: Procedure Call

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. }

Page 48: Procedure Call

48

Permutation

.file "permute.c"

.section .rdata,"dr"

LC0:

.ascii "%d\0"

.text

.globl _permute

.def _permute; .scl 2; .type 32; .endef

Page 49: Procedure Call

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

Page 50: Procedure Call

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

Page 51: Procedure Call

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

Page 52: Procedure Call

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]

Page 53: Procedure Call

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

Page 54: Procedure Call

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

Page 55: Procedure Call

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

Page 56: Procedure Call

56

Permutation

addl $1, -12(%ebp) # i = i + 1

L5:

movl -12(%ebp), %eax

cmpl 16(%ebp), %eax

jle L6

leave

ret

Page 57: Procedure Call

57

Permutation

int a[]={1,2,3,4};

void main()

{

permute(a, sizeof(a)/sizeof(a[0]), sizeof(a)/sizeof(a[0])-1);

}

Page 58: Procedure Call

58

Permutation

.globl _a

.data

.align 4

_a:

.long 1

.long 2

.long 3

.long 4

Page 59: Procedure Call

59

Permutation

.text

_main:

………

movl $3, 8(%esp)

movl $4, 4(%esp)

movl $_a, (%esp)

call _permute

………

ret