CSC448: Code Generation: Run-Time Environment V [6/14] Previous pageContentsNext page

What if recursive procedure calls are permitted?

A stack allows fast allocation and deallocation of activation records.

The position of local variables is not known at compile-time.

Generated code expects to find local variables at a fixed offset from the current activation record (in a C-like language).

On x86:

Procedures and functions communicate by passing arguments and return values.

There are several calling conventions in common use on x86, but we will use the following convention:

For example, f(1,2,3) might compile to:

pushl $3           // push parameter onto stack
pushl $2           // push parameter onto stack
pushl $1           // push parameter onto stack
call f             // store address of next instruction on stack, jump to f (set eip)
addl $12, %esp     // deallocate space for actual parameters

Callee executes the preamble:

pushl %ebp         // store old base pointer
movl  %esp, %ebp   // set new base pointer
subl  $12, %esp    // allocate space for local variables (three in this case)

Callee executes the postamble:

movl %ebp, %esp    // deallocate space for local variables
pop  %ebp          // restore old base pointer
ret                // pop address of instruction from stack and jump there (set eip)

Note that the activation record of the caller grows temporarily before the call (as arguments are pushed onto the stack), and shrinks after the call (when the stack pointer is moved upwards).

push = decrement esp then put data at new esp. pop = get data from esp then increment esp.

The arguments are reversed to allow procedures or functions with a variable number of arguments.

Suppose main(argv,argc){x} calls f(a,b,c){y,z} calls g(d,e){w}.

      0x1000      argc (parameter of main)
      0x0FFC      argv (parameter of main)
      0x0FF8      0x???? = %eip for os/runtime system (return address from main)
  +-> 0x0FF4      0x???? = %ebp for os/runtime system (return frame from main)
  |   0x0FF0      x (local variable of main)
  |
  |   0x0FEC      c (parameter of f)
  |   0x0FE8      b (parameter of f)
  |   0x0FE4      a (parameter of f)
  |   0x0FE0      0x???? = %eip for main (return address from f)
  +-- 0x0FDC <-+  0x0FF4 = %ebp for main (return frame from f)
      0x0FD8   |  y (local variable of f)
      0x0FD4   |  z (local variable of f)
               |
      0x0FD0   |  e (parameter of g)
      0x0FCC   |  d (parameter of g)
      0x0FC8   |  0x???? = %eip for f (return address from g)
+---> 0x0FC4 --+  0x0FDC = %ebp for f (return frame from g)
| +-> 0x0FC0      w (local variable of g
| |
| +-- %esp = 0x0FC0
+---- %ebp = 0x0FC4

e = 12(%ebp)  (parameters are positive)
d =  8(%ebp)  (parameters are positive)
w = -4(%ebp)  (local variables are negative)

Variables indexed w.r.t. %ebp.

End of allocated space determined by %esp.

Previous pageContentsNext page