Bird
Raised Fist0
ARM Architectureknowledge~10 mins

Subroutine call convention (AAPCS) in ARM Architecture - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Subroutine call convention (AAPCS)
Caller prepares arguments in registers R0-R3
↓
Caller pushes extra arguments on stack if >4
↓
Caller executes BL (branch with link) to subroutine
↓
Subroutine saves LR (R14) if needed
↓
Subroutine uses R0-R3 for parameters
↓
Subroutine uses R4-R11 as callee-saved registers
↓
Subroutine executes instructions
↓
Subroutine places return value in R0
↓
Subroutine restores saved registers and returns with BX LR
↓
Caller resumes, uses return value from R0
Shows the step-by-step flow of how arguments are passed, subroutine is called, registers saved/restored, and return value passed back following AAPCS.
Execution Sample
ARM Architecture
MOV R0, #5
MOV R1, #10
BL add_two_numbers
; result in R0
Caller sets two arguments in R0 and R1, calls subroutine add_two_numbers, which returns sum in R0.
Analysis Table
StepActionRegisters/Stack StateNotes
1Caller sets R0=5, R1=10R0=5, R1=10First two arguments in registers
2Caller executes BL add_two_numbersLR=return_addressLink register stores return address
3Subroutine saves LR if neededStack: push LRPreserve return address if subroutine calls others
4Subroutine uses R0=5, R1=10 as parametersR0=5, R1=10Parameters ready for use
5Subroutine computes sum: R0=R0+R1R0=15Return value placed in R0
6Subroutine restores LR from stackStack: pop LRRestore return address
7Subroutine returns with BX LRPC=LRReturn to caller
8Caller resumes, reads result from R0R0=15Result available in R0
💡 Subroutine returns to caller with result in R0, completing the call.
State Tracker
RegisterStartAfter Step 1After Step 4After Step 5After Step 8
R0undefined551515
R1undefined10101010
LRundefinedreturn_addresssaved on stacksaved on stackreturn_address restored
Key Insights - 3 Insights
Why are only registers R0 to R3 used for passing arguments initially?
Because AAPCS defines that the first four arguments go into R0-R3 for efficiency; extra arguments go on the stack (see execution_table step 1 and 2).
What happens if the subroutine calls another subroutine? How is the return address preserved?
The subroutine saves the LR (link register) on the stack before calling another subroutine (step 3), then restores it before returning (step 6).
Where is the return value placed after the subroutine finishes?
The return value is placed in R0 register (step 5 and 8), so the caller can read it immediately after return.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 5, what is the value of R0?
A15
B5
C10
Dundefined
💡 Hint
Check the 'Registers/Stack State' column at step 5 in execution_table.
At which step does the subroutine save the return address (LR) on the stack?
AStep 2
BStep 6
CStep 3
DStep 7
💡 Hint
Look for 'push LR' in the 'Registers/Stack State' column in execution_table.
If the caller had 5 arguments instead of 2, where would the 5th argument be placed?
AIn R3 register
BOn the stack
CIn R4 register
DIn LR register
💡 Hint
Recall that only R0-R3 hold first 4 arguments; extras go on stack (see key_moments question 1).
Concept Snapshot
AAPCS subroutine call:
- First 4 args in R0-R3 registers
- Extra args pushed on stack
- Caller uses BL to call subroutine
- Subroutine saves LR if calls others
- Return value in R0
- Return with BX LR
- Callee-saved registers R4-R11 preserved by subroutine
Full Transcript
This visual execution trace shows the ARM AAPCS subroutine call convention. The caller places up to four arguments in registers R0 to R3. If there are more than four arguments, the extras are pushed onto the stack. The caller then calls the subroutine using the BL instruction, which saves the return address in the link register (LR). The subroutine saves LR on the stack if it calls other subroutines to preserve the return address. The subroutine uses R0-R3 to access parameters and places the return value in R0. Before returning, it restores LR from the stack and returns using BX LR. The caller then resumes execution and reads the result from R0. This convention ensures efficient parameter passing and return value handling while preserving necessary registers.

Practice

(1/5)
1. According to the AAPCS, which registers are primarily used to pass the first four arguments to a subroutine?
easy
A. r0 to r3
B. r4 to r7
C. r8 to r11
D. lr and pc

Solution

  1. Step 1: Understand argument passing in AAPCS

    The AAPCS specifies that the first four arguments to a subroutine are passed using registers r0, r1, r2, and r3.
  2. Step 2: Identify the correct register range

    Registers r4 to r11 are used for other purposes, and lr (link register) stores the return address, not arguments.
  3. Final Answer:

    r0 to r3 -> Option A
  4. Quick Check:

    Arguments passed in r0-r3 [OK]
Hint: Remember: first 4 args in r0-r3 registers [OK]
Common Mistakes:
  • Confusing argument registers with callee-saved registers
  • Thinking lr or pc hold arguments
  • Assuming stack is always used first
2. Which register is used to store the return address when a subroutine is called under AAPCS?
easy
A. lr
B. r0
C. pc
D. sp

Solution

  1. Step 1: Identify the purpose of the link register (lr)

    In AAPCS, the link register (lr) holds the return address when a subroutine is called.
  2. Step 2: Differentiate from other registers

    r0 is for return values, pc is the program counter (current instruction), and sp is the stack pointer, not for return addresses.
  3. Final Answer:

    lr -> Option A
  4. Quick Check:

    Return address stored in lr [OK]
Hint: Return address always saved in lr register [OK]
Common Mistakes:
  • Confusing lr with pc (program counter)
  • Thinking r0 holds return address
  • Assuming sp stores return address
3. Consider a subroutine that takes 5 integer arguments. According to AAPCS, how are these arguments passed?
medium
A. All 5 arguments passed in r0 to r4
B. First 4 in r0 to r3, 5th on the stack
C. All 5 arguments passed on the stack
D. First 3 in r0 to r2, remaining 2 in r3 and r4

Solution

  1. Step 1: Recall argument passing rules for more than 4 arguments

    AAPCS passes the first 4 arguments in registers r0 to r3. Any additional arguments are passed on the stack.
  2. Step 2: Apply to 5 arguments

    For 5 arguments, the first 4 go into r0-r3, and the 5th argument is placed on the stack.
  3. Final Answer:

    First 4 in r0 to r3, 5th on the stack -> Option B
  4. Quick Check:

    Extra args beyond 4 go on stack [OK]
Hint: Only first 4 args in registers; rest go on stack [OK]
Common Mistakes:
  • Assuming all args fit in registers
  • Passing 5th arg in r4 incorrectly
  • Ignoring stack usage for extra args
4. A programmer notices that after a subroutine call, the value in register r4 is unexpectedly changed. What is the most likely cause under AAPCS?
medium
A. r4 is a caller-saved register and was not preserved by the caller
B. r4 holds the return address and was corrupted
C. r4 is used to pass arguments and was overwritten
D. r4 is a callee-saved register and the callee did not save it

Solution

  1. Step 1: Understand register saving responsibilities

    Under AAPCS, registers r4 to r11 are callee-saved, meaning the called function must save and restore them if it uses them.
  2. Step 2: Identify the cause of unexpected change

    If r4 changed unexpectedly, it means the callee did not save and restore it properly, causing corruption.
  3. Final Answer:

    r4 is a callee-saved register and the callee did not save it -> Option D
  4. Quick Check:

    Callee must save r4-r11 [OK]
Hint: Callee saves r4-r11; caller saves r0-r3 [OK]
Common Mistakes:
  • Thinking r4 is caller-saved
  • Confusing argument registers with saved registers
  • Assuming r4 holds return address
5. You need to write a subroutine that returns a 64-bit integer result. According to AAPCS, how should the return value be passed back to the caller?
hard
A. On the stack, not in registers
B. In r0 only, using 64 bits
C. In r0 and r1 combined
D. In r2 and r3 combined

Solution

  1. Step 1: Recall return value passing rules for 64-bit values

    AAPCS specifies that 64-bit return values are passed using two registers: r0 and r1 combined.
  2. Step 2: Eliminate incorrect options

    r0 alone holds 32 bits, so it cannot hold 64-bit values. Stack is not used for normal return values. r2 and r3 are not used for return values.
  3. Final Answer:

    In r0 and r1 combined -> Option C
  4. Quick Check:

    64-bit return uses r0 and r1 [OK]
Hint: 64-bit returns use r0 and r1 registers together [OK]
Common Mistakes:
  • Assuming 64-bit fits in r0 alone
  • Returning via stack unnecessarily
  • Using wrong registers for return
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