Necesary condition for correctly returning to its caller:
|
When we store parameters and local variables in the runtime stack:
|
A subroutine must clean up the runtime stack correctly before it can return !!
|
I will show you the subroutine postlude code next....
Before the postlude code starts tearing down the stack, the stack frame looks like this:
Postlude code: |
(1) De-allocate the space reserved for the local variables
Postlude code:
mov sp, fp
|
(2) Restore the saved value of FP back into the FP register (used by the caller)
Postlude code:
mov sp, fp
pop {fp}
|
Finally, we return to the caller because the return address is the top of the runtime stack !
(3) return to the caller (by popping the return address into PC):
Postlude code:
mov sp, fp
pop {fp}
pop {pc} // Execution goes back to the caller !
|
Note: the program will return to its caller and execute the instruction after the bl instruction
A (non-leaf) subroutine always executes this prelude code at its start:
push {lr}
push {fp}
mov fp, sp
sub sp, sp, #n // n depends on # local variables
|
A (non-leaf) subroutine always executes this postlude code when it returns (to its caller):
mov sp, fp
pop {fp}
pop {pc}
|
Notice the
LIFO
ordering:
insert: push lr, push fp
remove: pop fp, push pc
Important fact:
|
The runtime stack contains the following when the function returns (pop {pc}:
The caller must clean up the parameters from the runtime stack after the function return:
The caller's function call code:
push parameters on stack
bl function
clean up the parameters pushed on the stack !!!
|
The caller must clean up the parameters from the runtime stack after the function return:
The caller's function call code:
push parameters on stack
bl function
add sp, sp #n // n = 4 * # params pushed
|
DEMO: /home/cs255001/demo/asm/8-sub/pre+postlude.s