|
Once you understand this, it's very easy to solve the problem so you don't lose the return address.
We start with the structure of a leaf method that was discussed prviously:
leafMethod:
....
.... (instructions in the method)
....
/* -------------------------------------------
End of method, we need to return to caller
------------------------------------------- */
mov pc, lr
|
We must save the return address by pushing the lr register on the stack.
And: when the method returns, we must restore the return address using the value in the stack.
So the structure of a non-leaf method is:
nonLeafMethod:
push {lr} // Save return address on stack
....
.... (instructions in the method)
....
/* -------------------------------------------
End of method, we need to return to caller
------------------------------------------- */
pop {lr} // Restore return address
mov pc, lr // Return to caller
|
Instead of popping the top of the stack into the lr register and then moving the lr register into the pc register, we can simply pop the return address directly into the pc register !!!
So a better solution is:
nonLeafMethod:
push {lr} // Save return address on stack
....
.... (instructions in the method)
....
/* -------------------------------------------
End of method, we need to return to caller
------------------------------------------- */
pop {pc} // Return to caller !!!
|
public static void main(String[] args)
{
A( );
}
public static void A( )
{
...
B( ); // Calls B( )
...
}
public static void B( )
{
... // Does not call any method/function
...
}
|
Solution:
main:
mov r0, #1111
mov r1, #1111
bl A
mov r2, #2222
mov r3, #2222
bl A
mov r4, #3333
mov r5, #3333
Stop:
A:
push {lr} // Save return address
mov r0, #7777
mov r1, #7777
bl B // Overwrites lr, it's OK, we saved it !!!
mov r2, #8888
mov r3, #8888
pop {pc} // A returns to main !!!
B:
mov r0, #9999
mov r1, #9999
mov pc, lr // B can return to A
|
How to run the program:
|