The structure of the stack frame - Revisited

Here is the (original) sequence that contains the problem (before we fix it):

How to fix:   save the FP register on the stack and restore the FP register before we exit

The structure of the stack frame - Revisited

Here is the complete sequence of actions to create a stack frame:

Let's take a look at the structure of the stack frame (activation record)

The structure of the stack frame - build it from scratch

(1) The stack frame is empty right before we call a function:

Initial state: the stack frame for the function call f( ) is empty

The structure of the stack frame - build it from scratch

(2) The caller passes the parameters by pushing them on the stack:

The stack frame first contains the parameters of the function f( )

The structure of the stack frame - build it from scratch

(3) The bl instruction will jump to the function:

The stack frame is unchanged

The structure of the stack frame - build it from scratch

(4) The function f will save the the return address on the stack:

The stack frame now has parameters + return address

The structure of the stack frame - build it from scratch

(5) The function f must also save the the base address in FP in the stack:

The stack frame now has parameters + return address + old FP

The structure of the stack frame - build it from scratch

(6) The function f now safely establish the base address of the stack frame in FP

FP points to the "middle" of the (unfinished) stack frame

The structure of the stack frame - build it from scratch

(7) The function f will create its local variables using the stack:

The stack frame now has parameters + return address + old FP + local variables

How to create local variables on the runtime stack
 

  • You can use an push instruction to create one int typed variable on the runtime stack

    So you could use a number of push instructions to creates as many variables as you need...

  • A quicker (and better) way:

            sub  sp, sp, #n              
      

    will allocate n bytes on the runtime stack

    Use n = 4×k to allocate k integer variables on the runtime stack

The prelude code of a subroutine with parameters and local variables on stack

Previously we saw that a subroutine always begins with these 4 assembler instructions:

The prelude code of a subroutine with parameters and local variables on stack

Using the sub instruction to allocate local variables:

The prelude code of a subroutine with parameters and local variables on stack
 

The prelude code of a subroutine with parameters and local variables on stack:

     push   {lr}         // Save return address
     push   {fp}         // Save caller's FP
     mov    fp, sp       // Set up base address in FP
     sub    sp, sp, #n   // Allocate n/4 int local variables  

The prelude code always appear as the first 4 assembler instruction in (non-leaf) subroutines that must uses the runtime stack to store their local variables and parameters

Summary: the structure of the stack frame

The stack frame is the data structure used to store the parameters and local variables of an active function

The stack frame always has the following structure:

The parameters and local variables are access using FP as base address

The figure gives the offsets that you need to use to access the parameters and local variables