This analogy is also applicable in function calls:
|
|
|
Example:
public static void main(String[] args) { A( ); } public static void A( ) { ... B( ); // Calls B( ) ... } public static void B( ) { ... // Does not call any method/function ... } |
Methods main( ) and A( ) are non-leaf methods/functions
Method B( ) is a leaf method/function
public static void main(String[] args) { A( ); } public static void A( ) { ... B( ); // Calls B( ) ... } public static void B( ) { ... // Does not call any method/function ... } |
If we naively use what we have learned, we will get the following program (I used some dummy instructions between the bl and mov pc, lr instructions to show where the program is executing):
main: mov r0, #1111 mov r1, #1111 bl A mov r2, #1111 mov r3, #1111 Stop: A: mov r0, #2222 mov r1, #2222 bl B // Overwrites lr (A's return address to main !) mov r2, #2222 mov r3, #2222 mov pc, lr // A fails to return to main !!! B: mov r0, #9999 mov r1, #9999 mov pc, lr // B succeeds to return to A |
If you run this program in EGTAPI, you will see these instruction executed:
mov r0, #1111 mov r1, #1111 bl A A: mov r0, #2222 mov r1, #2222 bl B B: mov r0, #9999 mov r1, #9999 mov pc, lr // Returns to A mov r2, #2222 // Second half of A mov r3, #2222 mov pc, lr // Jumps to instruction AFTER "bl B" !!! mov r2, #2222 // Second half of A mov r3, #2222 mov pc, lr // Jumps to instruction AFTER "bl B" !! mov r2, #2222 // Second half of A mov r3, #2222 mov pc, lr // Jumps to instruction AFTER "bl B" !! .... (infinite loop !!) (Because the LR registers contains the return address used by B !!! and A is using it to return to main - failure !!!) |
The reason that the program behaves this way is because:
|
How to run the program:
|
|
|
Each type of information must be stored as efficiently as possible !!
These data structures should have included:
|
We will use the stack data structure to store return addresses because of the ordering in which the method calls returns:
|
The stack is the most efficient way to store return addresses because it matches the call/return ordering of methods/function