Efficient loop construction in ARM Architecture - Time & Space Complexity
When writing loops in ARM assembly, it is important to understand how the number of instructions executed grows as the loop runs more times.
We want to know how the time to complete the loop changes as the number of repetitions increases.
Analyze the time complexity of the following ARM assembly loop.
MOV R0, #10 // Set loop count to 10
MOV R1, #0 // Initialize counter
loop_start:
ADD R1, R1, #1 // Increment counter
CMP R1, R0 // Compare counter with loop count
BLT loop_start // Branch if less than loop count
This code runs a loop 10 times, incrementing a register from 1 to 10.
In this loop, the main repeated steps are:
- Primary operation: The instructions inside the loop: ADD, CMP, and BLT.
- How many times: These instructions run once for each loop iteration, which is the loop count value.
As the loop count increases, the number of times the loop instructions run increases directly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 30 instructions (3 per loop x 10) |
| 100 | About 300 instructions |
| 1000 | About 3000 instructions |
Pattern observation: The total instructions grow in a straight line as the loop count grows.
Time Complexity: O(n)
This means the time to complete the loop grows directly in proportion to the number of times the loop runs.
[X] Wrong: "The loop runs in constant time because the instructions inside are simple."
[OK] Correct: Even simple instructions add up when repeated many times, so the total time depends on how many times the loop runs.
Understanding how loops affect execution time is a key skill in low-level programming and helps you write efficient code that scales well.
"What if we replaced the conditional branch with a decrement and branch if not zero? How would the time complexity change?"
Practice
Solution
Step 1: Understand loop efficiency
Efficient loops reduce the number of instructions and cycles needed to repeat tasks.Step 2: Identify benefits of efficient loops
Fewer instructions mean faster execution and less power consumption.Final Answer:
They make the program run faster and use less power -> Option DQuick Check:
Efficient loops = faster + less power [OK]
- Thinking loops increase program size
- Assuming loops make code harder to read
- Believing loops remove all instructions
Solution
Step 1: Identify instruction for decrement and flag update
SUBS subtracts and updates condition flags, useful for loop counters.Step 2: Confirm usage in loops
SUBS combined with BNE (branch if not equal) creates efficient loops.Final Answer:
SUBS -> Option AQuick Check:
SUBS decreases counter and sets flags [OK]
- Choosing ADD which adds instead of subtracts
- Using MOV which only copies values
- Selecting NOP which does nothing
MOV R0, #5
loop:
SUBS R0, R0, #1
BNE loop
What will be the final value in register R0 after the loop finishes?Solution
Step 1: Trace the loop iterations
R0 starts at 5, each loop subtracts 1 and checks if zero. Loop runs while R0 != 0.Step 2: Understand SUBS and BNE behavior
When R0 reaches 1, SUBS makes it 0, BNE skips. But SUBS subtracts before checking, so last value is 0.Step 3: Check final register value
Actually, SUBS subtracts 1 each time, so after last iteration R0 becomes 0, then BNE fails and loop ends.Final Answer:
0 -> Option BQuick Check:
Loop ends when R0 = 0 [OK]
- Thinking R0 stays at initial value
- Assuming R0 becomes negative
- Confusing loop exit condition
MOV R1, #3
start:
SUB R1, R1, #1
BNE startSolution
Step 1: Check instruction for loop counter decrement
SUB does not update condition flags, so BNE cannot check zero condition correctly.Step 2: Correct instruction usage
SUBS subtracts and updates flags, enabling BNE to branch properly.Final Answer:
SUB should be SUBS to update flags -> Option CQuick Check:
Use SUBS for loops with BNE [OK]
- Ignoring flag update requirement
- Changing MOV unnecessarily
- Misunderstanding branch instructions
Solution
Step 1: Analyze loop counter and sum update
R0 starts at 10, SUBS decrements and updates flags, ADD adds current R0 to R2.Step 2: Check branch condition
BNE loops while R0 != 0, correctly counting down from 9 to 0 (since SUBS subtracts before add).Step 3: Confirm sum correctness
Since SUBS subtracts first, R0 goes 9 to 0, sum includes 9 down to 0, which sums 45 (1 to 9). To include 10, initial ADD before loop needed, but given options, this is best.Final Answer:
SUBS R0, R0, #1; ADD R2, R2, R0; BNE loop -> Option AQuick Check:
SUBS + BNE + ADD with R0 counter [OK]
- Using BEQ instead of BNE for loop
- Using SUB without flag update
- Adding constant 1 instead of counter value
Ready to prove it?
Pass the test and this pattern moves unknown
