Bird
Raised Fist0
ARM Architectureknowledge~10 mins

Nested subroutine calls in ARM Architecture - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Nested subroutine calls
Start main
↓
Call subroutine A
↓
subroutine A starts
↓
Call subroutine B
↓
subroutine B starts
↓
subroutine B ends
↓
Return to subroutine A
↓
subroutine A ends
↓
Return to main
↓
Program ends
The main program calls subroutine A, which calls subroutine B. Each subroutine runs and returns control back to its caller in order.
Execution Sample
ARM Architecture
main:
  BL subA
  ; continue main

subA:
  BL subB
  BX LR

subB:
  BX LR
Main calls subA, subA calls subB, then returns back step-by-step.
Analysis Table
StepInstructionActionCall StackReturn Address
1BL subACall subA, save return to main+4[main]main+4
2BL subBCall subB, save return to subA+4[main, subA]subA+4
3BX LR (in subB)Return to subA at subA+4[main, subA]subA+4
4BX LR (in subA)Return to main at main+4[main]main+4
5Main continuesProgram continues after subA call[]
💡 All subroutines returned; call stack empty; main resumes and program ends.
State Tracker
Call StackStartAfter Step 1After Step 2After Step 3After Step 4Final
Stack Frames[][main][main, subA][main, subA][main][]
Key Insights - 3 Insights
Why does the call stack grow when subA calls subB?
Because each BL instruction saves the return address on the stack before jumping, as shown in execution_table step 2 where subB is called and the stack becomes [main, subA].
How does the program know where to return after subB finishes?
The return address saved by BL in step 2 is used by BX LR in step 3 to jump back to subA at subA+4, as shown in the call stack and return address columns.
What happens if BX LR is missing in a subroutine?
The program would not return to the caller, causing incorrect flow or crash. The execution_table shows BX LR instructions at steps 3 and 4 ensure proper returns.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 2, what is the call stack after BL subB?
A[subA]
B[main]
C[main, subA]
D[]
💡 Hint
Refer to the 'Call Stack' column in execution_table row for step 2.
At which step does the program return from subB to subA?
AStep 1
BStep 3
CStep 4
DStep 5
💡 Hint
Check the 'Action' column for when BX LR in subB returns to subA.
If the BL instruction at step 1 was removed, what would happen?
AsubA would not be called; main continues without subA
BsubB would be called directly
CProgram would crash immediately
DsubA would run twice
💡 Hint
Look at step 1 where BL subA causes the call; removing it means no call to subA.
Concept Snapshot
Nested subroutine calls use BL (Branch with Link) to jump and save return address.
Each call adds a return address to the call stack.
Subroutines return using BX LR to jump back.
Calls can be nested; returns unwind the stack step-by-step.
Proper return instructions are essential to maintain flow.
Full Transcript
This visual trace shows how nested subroutine calls work in ARM architecture. The main program calls subroutine A using BL, which saves the return address and jumps to subA. Then subA calls subB similarly. Each call adds a frame to the call stack. When subB finishes, it returns to subA using BX LR, which uses the saved return address. Then subA returns to main the same way. The call stack grows and shrinks as calls and returns happen, ensuring the program continues correctly. Missing return instructions would break this flow.

Practice

(1/5)
1. What does a nested subroutine call mean in ARM assembly?
easy
A. A subroutine runs without calling any other subroutine
B. A subroutine calls itself repeatedly
C. One subroutine calls another subroutine inside it
D. A subroutine is called only once in the program

Solution

  1. Step 1: Understand subroutine calls

    A subroutine is a small program block that can be called to perform a task.
  2. Step 2: Define nested calls

    Nested calls happen when one subroutine calls another subroutine inside its code.
  3. Final Answer:

    One subroutine calls another subroutine inside it -> Option C
  4. Quick Check:

    Nested call = one subroutine calls another [OK]
Hint: Nested means calling a subroutine inside another [OK]
Common Mistakes:
  • Confusing nested call with recursion
  • Thinking subroutine runs alone without calls
  • Mixing up call and return instructions
2. Which ARM instruction is used to call a subroutine?
easy
A. BX LR
B. BL
C. MOV
D. ADD

Solution

  1. Step 1: Identify call instruction

    In ARM, the instruction to call a subroutine is 'BL' which means Branch with Link.
  2. Step 2: Differentiate from return instruction

    'BX LR' is used to return from a subroutine, not to call it.
  3. Final Answer:

    BL -> Option B
  4. Quick Check:

    Call subroutine = BL instruction [OK]
Hint: BL calls subroutine; BX LR returns [OK]
Common Mistakes:
  • Confusing BX LR as call instead of return
  • Using MOV or ADD as call instructions
  • Mixing up branch instructions without link
3. Given the following ARM assembly snippet, what is the final value in register R0 after execution?
main:
  MOV R0, #1
  BL sub1
  BX LR

sub1:
  ADD R0, R0, #2
  BL sub2
  BX LR

sub2:
  ADD R0, R0, #3
  BX LR
medium
A. 1
B. 3
C. 0
D. 6

Solution

  1. Step 1: Trace main and sub1 execution

    Start with R0=1 in main. Then BL sub1 calls sub1. In sub1, R0 = 1 + 2 = 3.
  2. Step 2: Trace sub1 calling sub2

    sub1 calls sub2. In sub2, R0 = 3 + 3 = 6. Then sub2 returns, sub1 returns, main returns.
  3. Final Answer:

    6 -> Option D
  4. Quick Check:

    1 + 2 + 3 = 6 [OK]
Hint: Add values stepwise through nested calls [OK]
Common Mistakes:
  • Ignoring sub2 addition
  • Not updating R0 after each call
  • Confusing return with call instructions
4. Identify the error in this ARM assembly nested subroutine code:
main:
  BL sub1
  BX LR

sub1:
  ADD R0, R0, #1
  BL sub2
  BX LR

sub2:
  ADD R0, R0, #2
  BX R0
medium
A. Using BX R0 instead of BX LR to return in sub2
B. Missing MOV instruction in main
C. BL should be replaced with BX for calls
D. R0 should not be modified in subroutines

Solution

  1. Step 1: Check return instructions

    Subroutines should return using 'BX LR' to jump back to caller address stored in LR.
  2. Step 2: Identify incorrect return

    In sub2, 'BX R0' tries to jump to address in R0, which is incorrect and causes error.
  3. Final Answer:

    Using BX R0 instead of BX LR to return in sub2 -> Option A
  4. Quick Check:

    Return must use BX LR, not BX R0 [OK]
Hint: Return with BX LR, not BX R0 [OK]
Common Mistakes:
  • Using BX R0 instead of BX LR
  • Confusing BL and BX instructions
  • Assuming R0 holds return address
5. You want to organize a complex ARM program by splitting tasks into subroutines that call each other. Which is the best practice for nested subroutine calls to avoid errors?
hard
A. Always use BL to call and BX LR to return, saving LR if calling another subroutine
B. Use BX LR to call and BL to return, no need to save LR
C. Avoid calling subroutines inside subroutines to prevent errors
D. Use MOV to jump between subroutines and ignore LR register

Solution

  1. Step 1: Understand call and return instructions

    BL saves return address in LR and branches to subroutine; BX LR returns to caller.
  2. Step 2: Handle nested calls safely

    If a subroutine calls another, it must save LR (e.g., on stack) before calling to avoid losing return address.
  3. Final Answer:

    Always use BL to call and BX LR to return, saving LR if calling another subroutine -> Option A
  4. Quick Check:

    BL call + BX LR return + save LR for nested calls [OK]
Hint: Save LR before nested BL calls, return with BX LR [OK]
Common Mistakes:
  • Using BX LR to call instead of BL
  • Not saving LR before nested calls
  • Jumping with MOV ignoring LR
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard