Bird
Raised Fist0
ARM Architectureknowledge~10 mins

Preserving callee-saved registers in ARM Architecture - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Preserving callee-saved registers
Function Entry
↓
Save callee-saved registers on stack
↓
Execute function body
↓
Restore callee-saved registers from stack
↓
Return to caller
When a function starts, it saves certain registers on the stack to keep their values safe. After running, it restores them before returning.
Execution Sample
ARM Architecture
push {r4, r5, lr}
...function body...
pop {r4, r5, pc}
This code saves registers r4, r5, and the return address (lr) at the start, runs the function, then restores them before returning.
Analysis Table
StepActionRegisters SavedStack StateRegisters RestoredReturn Address
1Function EntryNoneEmptyNoneUnknown
2Push r4, r5, lrr4, r5, lrr4, r5, lr saved on stackNoneUnknown
3Execute function bodyr4, r5, lrr4, r5, lr saved on stackNoneUnknown
4Pop r4, r5, pcr4, r5, lrEmptyr4, r5 restoredReturn to caller
5ReturnNoneEmptyAll restoredReturned
💡 Function returns after restoring callee-saved registers and loading return address into pc
State Tracker
VariableStartAfter Step 2After Step 3After Step 4Final
r4Original valueSaved on stackUnchangedRestored from stackOriginal value
r5Original valueSaved on stackUnchangedRestored from stackOriginal value
lrReturn addressSaved on stackUnchangedUsed to returnN/A (used)
StackEmptyr4, r5, lr pushedUnchangedPopped emptyEmpty
Key Insights - 3 Insights
Why do we save callee-saved registers at the start of the function?
Because these registers must keep their values after the function finishes, saving them on the stack protects their original values during the function execution (see execution_table step 2).
What happens if we forget to restore callee-saved registers before returning?
The caller might get wrong values in those registers, causing errors. The execution_table step 4 shows restoring them before return is essential.
Why is the link register (lr) saved and restored?
The lr holds the return address. Saving it ensures the function can return correctly after execution (see execution_table steps 2 and 4).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 2. Which registers are saved on the stack?
Ar4, r5, lr
Br0, r1, r2
Cpc, sp, lr
Dr6, r7, r8
💡 Hint
Check the 'Registers Saved' column at step 2 in the execution_table.
At which step does the function restore the saved registers?
AStep 2
BStep 4
CStep 3
DStep 5
💡 Hint
Look at the 'Registers Restored' column in the execution_table.
If the function did not save the lr register, what would happen?
AThe stack would overflow.
BThe function would still return correctly.
CThe return address might be lost, causing incorrect return.
DRegisters r4 and r5 would be corrupted.
💡 Hint
Refer to the key_moments about why lr is saved and restored.
Concept Snapshot
Preserving callee-saved registers:
- Save registers like r4, r5, lr on function entry (push).
- Execute function code safely.
- Restore registers before returning (pop).
- Ensures caller's register values stay unchanged.
- lr holds return address; must be saved/restored.
Full Transcript
When a function starts in ARM architecture, it saves certain registers called callee-saved registers, such as r4, r5, and the link register (lr), onto the stack. This protects their values while the function runs. After the function finishes its work, it restores these registers from the stack before returning to the caller. This process ensures that the caller's register values remain unchanged and the function returns correctly using the saved return address in lr.

Practice

(1/5)
1. What is the main purpose of preserving callee-saved registers in ARM architecture?
easy
A. To speed up the execution of the program
B. To allow the caller to modify registers freely
C. To keep the values intact across function calls
D. To reduce the number of registers used

Solution

  1. Step 1: Understand the role of callee-saved registers

    Callee-saved registers must keep their values unchanged after a function call to avoid breaking the caller's data.
  2. Step 2: Identify the purpose of preserving these registers

    Preserving means saving and restoring their values so the caller sees no change.
  3. Final Answer:

    To keep the values intact across function calls -> Option C
  4. Quick Check:

    Preserving registers = keeping values intact [OK]
Hint: Remember: callee saves to protect caller's data [OK]
Common Mistakes:
  • Thinking callee-saved registers speed up execution
  • Confusing callee-saved with caller-saved registers
  • Believing registers can be freely modified without saving
2. Which ARM assembly instruction is commonly used to save callee-saved registers at the start of a function?
easy
A. MOV
B. ADD
C. CMP
D. PUSH

Solution

  1. Step 1: Identify instruction to save registers

    The PUSH instruction stores registers onto the stack, preserving their values.
  2. Step 2: Confirm PUSH is used at function start

    Functions use PUSH to save callee-saved registers before modifying them.
  3. Final Answer:

    PUSH -> Option D
  4. Quick Check:

    Save registers = PUSH [OK]
Hint: PUSH saves registers on stack at function start [OK]
Common Mistakes:
  • Using MOV which copies but doesn't save to stack
  • Using ADD which changes values, not saves
  • Using CMP which compares values, not saves
3. Consider this ARM function snippet:
func:
  PUSH {r4, r5}
  MOV r4, #10
  MOV r5, #20
  POP {r4, r5}
  BX lr
What will be the value of registers r4 and r5 after returning to the caller?
medium
A. r4 and r5 unchanged from caller
B. r4 and r5 contain random values
C. r4 = 0, r5 = 0
D. r4 = 10, r5 = 20

Solution

  1. Step 1: Analyze PUSH and POP effect

    PUSH saves original r4 and r5 values on stack; POP restores them before return.
  2. Step 2: Understand MOV instructions inside function

    Inside function, r4 and r5 are changed, but POP restores original values before returning.
  3. Final Answer:

    r4 and r5 unchanged from caller -> Option A
  4. Quick Check:

    Saved and restored registers = unchanged after call [OK]
Hint: PUSH then POP restores original register values [OK]
Common Mistakes:
  • Assuming MOV changes persist after POP
  • Ignoring that POP restores saved registers
  • Thinking registers reset to zero automatically
4. A function modifies callee-saved registers but forgets to restore them before returning. What problem can this cause?
medium
A. The program may crash or behave unpredictably
B. The function will run faster
C. The caller's registers remain unchanged
D. The stack pointer will not be affected

Solution

  1. Step 1: Understand callee-saved register role

    These registers must be restored to keep caller's data intact.
  2. Step 2: Consequence of not restoring

    If not restored, caller sees wrong values, causing crashes or wrong behavior.
  3. Final Answer:

    The program may crash or behave unpredictably -> Option A
  4. Quick Check:

    Not restoring callee-saved = crashes/unpredictable [OK]
Hint: Not restoring callee-saved causes crashes [OK]
Common Mistakes:
  • Thinking it improves speed
  • Believing caller's registers stay safe without restore
  • Ignoring stack pointer effects
5. You have a function that uses registers r4, r5, and r6 (all callee-saved). Which sequence correctly preserves and restores these registers?
hard
A. MOV r4, #0 MOV r5, #0 MOV r6, #0 ...function body... BX lr
B. PUSH {r4, r5, r6} ...function body... POP {r4, r5, r6}
C. PUSH {r4} PUSH {r5} PUSH {r6} ...function body... POP {r4} POP {r5} POP {r6}
D. POP {r4, r5, r6} ...function body... PUSH {r4, r5, r6}

Solution

  1. Step 1: Identify correct saving method

    Registers must be pushed together at function start to save their original values.
  2. Step 2: Identify correct restoring method

    Registers must be popped in the same order before returning to restore original values.
  3. Step 3: Check options for correct sequence

    PUSH {r4, r5, r6} ...function body... POP {r4, r5, r6} pushes all three registers at once and pops them before return, which is correct.
  4. Final Answer:

    PUSH {r4, r5, r6} ...function body... POP {r4, r5, r6} -> Option B
  5. Quick Check:

    Push all then pop all = correct preservation [OK]
Hint: Push all callee-saved at start, pop all before return [OK]
Common Mistakes:
  • Pushing and popping registers separately in wrong order
  • Using POP before PUSH
  • Overwriting registers without saving
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