Bird
Raised Fist0
ARM Architectureknowledge~10 mins

Why subroutines enable modular assembly code in ARM Architecture - Visual Breakdown

Choose your learning style10 modes available
Concept Flow - Why subroutines enable modular assembly code
Start main program
↓
Call subroutine
↓
Save return address
↓
Execute subroutine code
↓
Return to main program
↓
Continue main program
The main program calls a subroutine, which saves where to return, runs its code, then returns control back to the main program.
Execution Sample
ARM Architecture
BL subroutine
...
subroutine:
  PUSH {LR}
  ; do work
  POP {LR}
  BX LR
This code calls a subroutine, saves the return address, does some work, then returns to the caller.
Analysis Table
StepActionRegister LR (Link Register)Program Counter (PC)Description
1Main program runsLR=unknownPC=main_startProgram starts running main code
2BL subroutine calledLR=address after BLPC=subroutine_startBranch with link saves return address in LR and jumps to subroutine
3PUSH {LR}LR=address after BLPC=subroutine_start+4Subroutine saves LR on stack to preserve return address
4Subroutine workLR=address after BLPC=subroutine_workSubroutine executes its instructions
5POP {LR}LR=address after BLPC=subroutine_endSubroutine restores LR from stack
6BX LRLR=address after BLPC=address after BLBranch back to the instruction after BL in main program
7Main program continuesLR=address after BLPC=address after BLMain program resumes after subroutine call
💡 Execution stops after returning from subroutine and continuing main program
State Tracker
VariableStartAfter Step 2After Step 3After Step 5After Step 6Final
LR (Link Register)unknownaddress after BLaddress after BLaddress after BLaddress after BLaddress after BL
PC (Program Counter)main_startsubroutine_startsubroutine_start+4subroutine_endaddress after BLaddress after BL
Key Insights - 3 Insights
Why does the BL instruction save the return address in LR?
BL saves the address of the next instruction in LR so the program knows where to return after the subroutine finishes, as shown in step 2 of the execution_table.
Why do we push and pop LR in the subroutine?
Pushing LR saves the return address on the stack to protect it if the subroutine calls other functions; popping LR restores it before returning, as seen in steps 3 and 5.
How does the program know where to continue after the subroutine?
The BX LR instruction branches back to the saved return address in LR, returning control to the main program at the correct spot, shown in step 6.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 2. What value does LR hold after the BL instruction?
AZero
BThe address of the subroutine start
CThe address of the instruction after BL
DThe current PC value
💡 Hint
Check the LR column at step 2 in the execution_table.
At which step does the subroutine restore the LR value from the stack?
AStep 5
BStep 3
CStep 4
DStep 6
💡 Hint
Look for the POP {LR} action in the execution_table.
If the subroutine did not push LR before calling another subroutine, what could happen?
AThe program would run faster
BThe return address might be lost or overwritten
CLR would hold the correct return address anyway
DThe subroutine would not execute
💡 Hint
Refer to the key_moments explanation about saving LR on the stack.
Concept Snapshot
Subroutines let assembly code be modular by allowing code reuse.
The BL instruction calls a subroutine and saves return address in LR.
Subroutines save LR on stack if they call others to protect return address.
BX LR returns control to the caller using saved address.
This enables clear, reusable, and maintainable code blocks.
Full Transcript
In ARM assembly, subroutines enable modular code by allowing the main program to call separate code blocks. The BL instruction saves the return address in the Link Register (LR) and jumps to the subroutine. The subroutine saves LR on the stack to protect it if it calls other subroutines. After completing its work, it restores LR and uses BX LR to return to the main program. This process allows code to be reused and organized in modules, making programs easier to write and maintain.

Practice

(1/5)
1. Why do subroutines help make assembly code modular?
easy
A. They break code into smaller, reusable parts
B. They make the code run faster by default
C. They remove the need for registers
D. They automatically optimize memory usage

Solution

  1. Step 1: Understand modularity in code

    Modular code means breaking a program into smaller, manageable pieces that can be reused.
  2. Step 2: Role of subroutines in assembly

    Subroutines allow code to be divided into reusable blocks, making it easier to manage and understand.
  3. Final Answer:

    They break code into smaller, reusable parts -> Option A
  4. Quick Check:

    Modularity = reusable parts [OK]
Hint: Subroutines = reusable code blocks for easier management [OK]
Common Mistakes:
  • Thinking subroutines speed up code automatically
  • Believing subroutines remove register use
  • Assuming subroutines optimize memory without effort
2. Which of the following is the correct way to call a subroutine named process_data in ARM assembly?
easy
A. JMP process_data
B. CALL process_data
C. BL process_data
D. RUN process_data

Solution

  1. Step 1: Identify ARM assembly call instruction

    In ARM assembly, the instruction to call a subroutine is BL (Branch with Link).
  2. Step 2: Compare options

    Only BL process_data uses BL, which is the correct ARM syntax for calling subroutines.
  3. Final Answer:

    BL process_data -> Option C
  4. Quick Check:

    ARM subroutine call = BL [OK]
Hint: ARM calls use BL, not CALL or JMP [OK]
Common Mistakes:
  • Using CALL which is not ARM syntax
  • Using JMP which is for jumps, not calls
  • Using RUN which is invalid in assembly
3. Consider this ARM assembly snippet:
BL calculate
MOV R0, #5
BL calculate
What is the main benefit of using the calculate subroutine twice here?
medium
A. It prevents the need for any branching instructions
B. It reduces code duplication by reusing the same code block
C. It avoids using registers for calculations
D. It makes the program run twice as fast automatically

Solution

  1. Step 1: Analyze the code snippet

    The subroutine calculate is called twice, showing reuse of the same code block.
  2. Step 2: Understand the benefit

    Reusing a subroutine avoids repeating the same instructions multiple times, reducing code size and duplication.
  3. Final Answer:

    It reduces code duplication by reusing the same code block -> Option B
  4. Quick Check:

    Subroutines reduce duplication [OK]
Hint: Calling subroutines twice reuses code, not speed [OK]
Common Mistakes:
  • Assuming calling twice doubles speed
  • Thinking registers are not used in subroutines
  • Believing subroutines remove all branches
4. You wrote this ARM assembly code to call a subroutine:
BL my_subroutine
MOV R1, #10
BX LR

But the program crashes after returning from my_subroutine. What is the likely error?
medium
A. The subroutine name is case-sensitive and must be uppercase
B. The MOV instruction is invalid after a subroutine call
C. The BX LR instruction should be replaced with BL
D. The subroutine did not preserve the link register (LR) before returning

Solution

  1. Step 1: Understand link register usage

    ARM uses the link register (LR) to store return address when calling subroutines with BL.
  2. Step 2: Identify common mistake

    If the subroutine modifies LR without saving/restoring it, the return address is lost, causing a crash on BX LR.
  3. Final Answer:

    The subroutine did not preserve the link register (LR) before returning -> Option D
  4. Quick Check:

    LR must be saved/restored in subroutines [OK]
Hint: Always save LR in subroutines to avoid crashes [OK]
Common Mistakes:
  • Thinking MOV after BL causes crash
  • Replacing BX LR with BL incorrectly
  • Assuming subroutine names are case-sensitive
5. You want to write modular ARM assembly code that calculates the sum of two numbers multiple times with different inputs. Which approach best uses subroutines to achieve this?
hard
A. Write a single subroutine that takes inputs via registers, returns sum in a register, and call it with different values
B. Write separate code blocks for each sum calculation without subroutines
C. Use a subroutine that hardcodes the input values inside it
D. Avoid subroutines and repeat the addition instructions each time

Solution

  1. Step 1: Understand modular design for repeated tasks

    Modular code uses subroutines that accept inputs and return outputs to reuse logic flexibly.
  2. Step 2: Apply to sum calculation

    A subroutine that takes numbers in registers and returns their sum allows calling it multiple times with different inputs, avoiding code repetition.
  3. Final Answer:

    Write a single subroutine that takes inputs via registers, returns sum in a register, and call it with different values -> Option A
  4. Quick Check:

    Reusable subroutine with inputs = modular code [OK]
Hint: Use input/output registers in subroutines for flexibility [OK]
Common Mistakes:
  • Hardcoding inputs inside subroutines
  • Repeating code instead of reusing subroutines
  • Avoiding subroutines for repeated calculations
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