We recommend using Visual Studio 2017

ARM Stack Frame Layout


The following list gives more information about ARM microprocessor stack frame layout.

  • The Register Save Area (RSA) holds the preserved values of permanent registers used by the function. It also contains the function return address.
  • The Locals and Temporaries area represents the stack space allocated for local variables and compiler-generated temporaries.
  • The first four words at the top of the stack can contain the values passed in R0-R3. Any of these values could be missing. The values should be stored in the R0-R3 if registers cannot hold the arguments for the entire function, or if the addresses for the arguments are in use.
    If a routine needs storage space for the first four words of arguments, it creates and initializes the storage at the top of the called function stack.
    If a register keeps an argument for the argument live range, the argument has no associated storage in the stack frame.

A frame pointer helps mitigate problems with the limited size of the bit field that specifies register-displacement-addressing offset. The frame pointer typically points to a fixed frame offset in the RSA or Local and Temporaries areas of the stack frame, but the pointer can point to other offsets within the frame. To more efficiently access data in large stack frames, a routine can establish another frame pointer.

  • A routine does not need to set up a stack frame unless it needs to save permanent registers, or to allocate space for locals or outgoing argument areas that are bigger than four words. The stack pointer and frame pointer addresses align on 4-byte boundaries.
  • If a routine has alloca() locals, the ARM specification requires a separate frame pointer register to access incoming arguments and locals.
    R11 is the assigned frame pointer for ARM, and R7 is the assigned frame pointer for THUMB.
    A leaf routine can use any free integer register as the frame pointer. A nonleaf routine must use a permanent register. The routine must not modify the frame pointer register between the prolog and epilog.
  • If a routine uses alloca(), everything in the frame at a lower address than the alloca() area is referenced relative to R13 and never contains a defined value at the time of an alloca() call. Thus, the alloca() operation never needs to copy this part of the stack frame, and no data relocation problems arise.
    Everything in the frame at an address higher than the alloca() area is referenced relative to the frame pointer, R11 for ARM or R7 for THUMB.