Linux Stack. Procedure Calls. Procedure Calls. Procedure Calls

IA32/Linux Stack • Memory managed with stack discipline • Register %esp stores the address of top element 0x0 Procedure Calls Instructions Functions...
Author: Mabel Hancock
43 downloads 1 Views 476KB Size
IA32/Linux Stack • Memory managed with stack discipline • Register %esp stores the address of top element

0x0

Procedure Calls Instructions Functions pushl src Fetch data at src

CS 217

Decrement %esp by 4 movl src, (%esp) popl dest

Stack pointer %esp

Top Top element

movl (%esp), dest Increment %esp by 4 Bottom

1

Procedure Calls

Procedure Calls

• Calling a procedure involves following actions o o o o o

2

• Requirements o o o o o o o

pass arguments save a return address transfer control to callee transfer control back to caller return results int add3(int a, int b, int c) { return a + b + c; }

Make a call to an arbitrary address Return back after the call sequence Handle nested procedure calls Save and restore caller’s registers Pass an arbitrary number of arguments Pass and return structures Allocate and deallocate space for local variables

• Procedure call and return instruction sequences collaborate to implement these requirements

foo(void) { int d; d = add3( 3, 4, 5 ); return d; } 3

4

Procedure Calls

Call and Return Instructions

• Requirements ¾ ¾ o o o o o

• Procedure call

Make a call to an arbitrary address Return back after the call sequence Handle nested procedure calls Save and restore caller’s registers Pass an arbitrary number of arguments Pass and return structures Allocate and deallocate space for local variables

o Push the return address on the stack o Jump to the procedure location

0

• Procedure return o Pop the return address off the stack o Jump to the return address

• Why using a stack?

• Procedure call and return instruction sequences collaborate to implement these requirements

Instructions Functions call addr pushl %eip jmp addr ret

Stack pointer %esp

Old eip

pop %eip Bottom

5

Nested Procedure Call

Procedure Calls

• A calls B, which calls C

• Requirements o o ¾ ¾ o o o

• Must even work when B is A A:

C:

B:

call B

6

call C

Make a call to an arbitrary address Return back after the call sequence Handle nested procedure calls Save and restore caller’s registers Pass an arbitrary number of arguments Pass and return structures Allocate and deallocate space for local variables

• Procedure call and return sequences collaborate to implement these requirements ret

ret

ret

7

8

Procedure Stack Structure

Stack Frame in Detail • Callee stack frame

• Stack frame

o Parameters for called functions o Local variables – If can’t keep in registers o Saved register context o Old frame pointer

o Each procedure call has a stack frame o Deal with nested procedure calls 0x0

• Stack Pointer



o Register %esp o Point to the top element of the stack Stack pointer Frame Pointer (%esp) o Register %ebp Frame pointer o Start of current stack frame (%ebp)

• Caller stack frame o Return address – Pushed by “call” instruction o Arguments for this call

Stack frame

• Before return, use “leave” instruction, which does

Stack frame

• Why using a frame pointer? o Pop off the entire frame before the procedure call returns

(%esp)

Callee frame (%ebp)

Arguments

Caller frame

movl %ebp, %esp popl %ebp

Stack frame

Local variables Saved registers Old ebp Return addr

Local variables Saved registers Old ebp

9

Procedure (Callee)

10

Procedure (Callee) in Action

.text

.text

.globl Foo

.globl Foo

Foo:

Foo:

pushl %ebp movl %esp, %ebp . . . leave

Callee frame (%ebp)

movl %ebp, %esp popl %ebp

movl %esp, %ebp . . . leave

Local variables Saved registers Old ebp Return addr Arguments

Caller frame

ret

pushl %ebp

(%esp)

movl %ebp, %esp popl %ebp 11

(%ebp) (%esp) (%ebp) (%esp) (%esp)

Local variables Saved registers Old ebp Return addr Arguments

Caller frame

ret

Local variables Saved registers Old ebp

(%esp)

(%ebp)

Local variables Saved registers Old ebp

12

Register Saving Options • Problem: a procedure needs to use registers, but o If you use the registers, their contents will be changed when returning to the caller o If we save registers on the stack, who is responsible?

IA32/Linux Register Saving Convention • Special stack registers

main: • • • movl $0x123, %edx call Foo addl %edx, %eax • • • ret

o %ebp, %esp

• Callee-save registers o %ebx, %esi, %edi o Old values saved on stack prior to using

• Caller-save registers

• Caller Save o Caller saves registers in its frame before calling

• “Callee Save” o Callee saves registers in its frame before using

%eax Caller-Save registers

%ecx %ebx Callee-Save registers

o %eax, %edx, %ecx o Save on stack prior to calling

Foo: • • • movl 8(%ebp), %edx addl $0x456, %edx • • • ret

%edx

%esi %edi %esp

Stack

%ebp

13

Procedure Calls

Passing Arguments to Procedure

• Requirements o o o o ¾ ¾ ¾

14

• Arguments are passed on stack in order

Set PC to arbitrary address Return PC to instruction after call sequence Handle nested procedure calls Save and restore caller’s registers Pass an arbitrary number of arguments Pass and return structures Allocate and deallocate space for local variables

0x0

o Push N-th argument first o Push 1st argument last

• Callee references the argument by o 1st argument: 8(%ebp) o 2nd argument: 12(%ebp) o ...

• Procedure call and return sequences collaborate to implement these requirements

• Passing result back by %eax o Caller is responsible for saving %eax register

15

(%esp)

Callee frame (%ebp)

Caller frame

Arguments build Local variables Saved registers Old ebp Return addr Arg1 .. . ArgN Local variables Saved registers Old ebp 16

Example: Passing Arguments

Allocation for Local Variables

.text .globl add3

int d;

• Local variables are stored in a stack frame

add3: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax addl 8(%ebp), %eax addl 16(%ebp), %eax leave ret .globl foo

int add3(int a, int b, int c) { return a + b + c; }

• Allocation is done by moving the stack pointer %esp subl $4, %esp

• Reference local variable by using register %ebp

foo:

foo(void) { d = add3( 3, 4, 5 ); return d; }

pushl movl pushl pushl pushl call movl leave ret .comm

%ebp %esp, %ebp $5 $4 $3 add3 %eax, d

d,4,4

{ return a + b + c; }

foo(void) { int d; d = add3( 3, 4, 5 ); return d; }

.text .globl add3 add3: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax addl 8(%ebp), %eax addl 16(%ebp), %eax leave ret .globl foo foo: pushl %ebp movl %esp, %ebp subl $4, %esp pushl $5 pushl $4 pushl $3 call add3 movl %eax, -4(ebp) leave ret

(%esp)

Callee frame (%ebp)

e.g. -4(%ebp)

Caller frame

Arguments build Local variables Saved registers Old ebp Return addr Arg1 .. . ArgN Local variables Saved registers Old ebp

17

Example: Local Variables int add3(int a, int b, int c)

0x0

18

Summary • Issues related to calling conventions o o o o o o

Stack frame for caller and callee Use esp and ebp registers Passing arguments on stack Saving registers on stack (caller save and callee save) Local variables on stack Passing result in eax register

• Procedure call instructions call, ret, leave

19

20