The Stack pushl * does %esp <- %esp - 4 movl *, (%esp) popl * - - PowerPoint PPT Presentation

the stack
SMART_READER_LITE
LIVE PREVIEW

The Stack pushl * does %esp <- %esp - 4 movl *, (%esp) popl * - - PowerPoint PPT Presentation

Function Implementation (x86-specific) double words are pushed and popped addr 0 dedicated register %esp contains address of item currently at top of stack (TOS) %esp The Stack pushl * does %esp <- %esp - 4 movl *, (%esp) popl *


slide-1
SLIDE 1

Function Implementation (x86-specific)

addr 0

double words are pushed and popped dedicated register %esp contains address of item currently at top of stack (TOS)

%esp

The Stack

slide-2
SLIDE 2

The Stack

pushl * popl *

does does

%esp <- %esp - 4 movl *, (%esp) movl (%esp), * %esp <- %esp + 4

slide-3
SLIDE 3

addr 0

%esp

The Stack

push $6 push $-1 push $3

slide-4
SLIDE 4

Layout of segments in memory

code data heap stack

addr 0

slide-5
SLIDE 5

What we need to know how to do. . . (what the compiler must be able to implement)

  • 1. call
  • 2. return
  • 3. AR and local variables
  • 4. return value
  • 5. parameters
slide-6
SLIDE 6
  • 1. call
  • remember the return address
  • go to fcn

this is such a common operation that the x86 architecture supports it with a single instruction

call fcn

does the equivalent of

push %eip jmp fcn

PC

addr 0

%esp

slide-7
SLIDE 7
  • 2. return

use the return address pushed onto the stack

ret

does the equivalent of

popl %eip

addr 0

%esp ra

slide-8
SLIDE 8

void c() { } void b() { c(); } void a() { b(); } main() { a(); }

sample code to show only call and return

c: ret b: call c L3: ret a: call b L2: ret main: call a L1:

addr 0

%esp

slide-9
SLIDE 9
  • 3. incorporate AR

For example, assume we need AR space for 3 ints. gcc on x86 allocates AR space in multiples of 16 bytes.

addr 0

%ebp ra %ebp %esp %esp Before fcn starts, but after the call instruction After fcn prologue prev %ebp

slide-10
SLIDE 10

prologue code pushl %ebp movl %esp, %ebp subl $16, %esp

addr 0

%ebp ra %ebp %esp %esp Before fcn starts, but after the call instruction After fcn prologue prev %ebp

slide-11
SLIDE 11

epilogue code leave does movl %ebp, %esp popl %ebp ret does popl %eip

addr 0

%ebp ra %ebp %esp %esp Before epilogue After epilogue prev %ebp

slide-12
SLIDE 12

Put local variables into AR:

void b() { int x, y, z; x = 1; y = 2; z = 3; c(); } b: pushl %ebp prologue movl %esp, %ebp subl $16, %esp movl $1, -12(%ebp) movl $2, -8(%ebp) movl $3, -4(%ebp) call c leave epilogue ret

%ebp ra %esp before epilogue prev %ebp

Z

y x

slide-13
SLIDE 13

int b() { c(); return 4; } b: call c movl $4, %eax leave ret

  • 4. return value

On x86, return value goes in %eax (by convention)

slide-14
SLIDE 14
  • 5. parameters

No room in registers on the x86, so parameters go onto the stack. Caller allocates space and places copies (for call by value). Child retrieves and uses copies.

main () { a( 1, 2, 3 ); } main: pushl %ebp movl %esp, %ebp subl $12, %esp movl $1, (%esp) movl $2, 4(%esp) movl $3, 8(%esp) call a leave ret

slide-15
SLIDE 15

addr 0

%ebp p1 p2 p3

main's

  • utgoing

parameters

slide-16
SLIDE 16

b: pushl %ebp movl %esp, %ebp movl 12(%ebp), %eax movl 8(%ebp), %edx add %edx, %eax popl %ebp ret a: pushl %ebp movl %esp, %ebp subl $8, %esp movl $4, (%esp) movl $5, 4(%esp) call b leave ret int b(int a1, int a2) { return (a1 + a2); } void a(int p1, int p2, int p3) { b(4,5); }

slide-17
SLIDE 17

addr 0

%ebp ra prev %ebp prev %ebp ra

b's AR a's AR

a2 a1 by convention, and to make the compiler's job easy, the first parameter will always be at 8(%ebp) p1 p2 p3

main's

  • utgoing

parameters

slide-18
SLIDE 18

addr 0

%ebp ra prev %ebp

current AR

P1 incoming is always at 8(%ebp) P1 out P2 out P3 out . .

(parameter build space)

local variables callee-saved regs P1 in P2 in . . %esp