Advanced Topics
Nested subroutines
The BL instruction always uses r14 to store the return address. This leads to a potential problem if one subroutine calls a further subroutine - how will the program find its way back to the original call?
There is also a second problem in that there are only so many registers available. The main program may have stored valuable information in some of the registers, but the subroutine (or its writer) won't necessarily know which registers are used or may need to use those registers for its own computations.
The solution to both these problems is to use a stack to preserve the value of the return address and the contents of any other registers.
BL | Sub1 | ; call first subroutine | |
. | ; first subroutine returns to here | ||
Sub1 | STMED | r13!, {r0-r3, r14} | ; push working registers r0 to r3 and link register onto stack |
. | ; perform computations | ||
BL | Sub2 | ; call second (nested) subroutine | |
. | ; second subroutine returns here | ||
LDMED | r13!, {r0-r3, r14} | ; pop old values of working registers r0 to r3 and r14 off stack | |
MOV | r15, r14 | ; return to main program |