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