|
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:
|