|
The data structure used to store a (non-leaf) subroutine's parameters and local variables is the stack frame (or activation record):
The FP register contains the base address to a stack frame object
A field (= a parameter or a local variable) stored inside the stack frame object is accessed using a offset from the base address in the FP register
How to call a (non-leaf) subroutine with k parameters:
// Push the parameters on the stack load parameter k into r0 push {r0} load parameter k-1 into r0 push {r0} .... load parameter 2 into r0 push {r0} load parameter 1 into r0 push {r0} bl Subroutine // Call the subroutine // Pop the parameters off the stack add sp, sp, #4×k // Clean up k int parameters |
The structure of a (non-leaf) subroutine that has n local variables
Subroutine:
// Prelude
push {lr} // Save return addr
push {fp} // Save caller's FP reg
mov fp, sp // Establish the base address
sub sp, sp, #4n // Allocate n local variables
...
... // Body of the subroutine
...
put the return value in the return location (usually r0)
// Postlude
mov sp, fp // De-allocates the local variables
pop {fp} // Restore the saved FP value
pop {pc} // Return to the caller
|