Assembly Guide — Loop Constructs and Iteration
In this tutorial, you will learn about Assembly Guide. We cover key concepts, practical examples, and best practices to help you master this topic.
Assembly loops use conditional jumps with counter registers (RCX) to create iteration patterns, supporting for loops, while loops, do-while loops, and idiomatic loop optimizations.
What You'll Learn
- While loop pattern
- For loop pattern
- Loop instruction
- Nested loops
- Loop optimizations
Why It Matters
Loops are fundamental to all non-trivial programs. Understanding assembly loops enables performance optimization. Durga Antivirus Pro uses loops for file scanning.
Real-World Use
Array processing, data structure traversal, search algorithms, and iterative computations.
flowchart LR
A["Loops"] --> B["While"]
B --> C["For"]
C --> D["Nested"]
D --> E["Optimization"]
A:::current --> B
style A fill:#2563eb,stroke:#2563eb,color:#fff
style B fill:#dbeafe,stroke:#2563eb,color:#1e40af
style C fill:#dbeafe,stroke:#2563eb,color:#1e40af
style D fill:#dbeafe,stroke:#2563eb,color:#1e40af
style E fill:#f1f5f9,stroke:#94a3b8,color:#64748b
While Loop
; High-level: while (condition) { body; }
; Pattern: check condition, jump to end if false, do body, jump back
jmp .check ; Jump to condition check
.loop:
; Loop body here
; ... instructions ...
.check:
cmp rax, 100
jl .loop ; If condition true, continue
.end:
; Code after loop
For Loop
; High-level: for (i = 0; i < n; i++) { body; }
mov rcx, 0 ; i = 0
.loop:
cmp rcx, 10 ; i < 10?
jge .end ; If not, exit
; Loop body (use RCX)
; ... instructions ...
inc rcx ; i++
jmp .loop
.end:
; Better: count down (faster comparison)
mov rcx, 10 ; count = n
.loop:
; Loop body
dec rcx ; count--
jnz .loop ; If count != 0, continue
LOOP Instruction
; LOOP: decrement RCX, jump if RCX != 0
; Slower than manual dec/jnz (on modern CPUs)
mov rcx, 10
.loop:
; Loop body
loop .loop ; dec rcx; jnz .loop
; LOOPE: loop while equal (ZF=1)
; LOOPNE: loop while not equal (ZF=0)
; Note: LOOP is rarely used in optimized code
; Manual dec rcx + jnz is preferred
Array Traversal
; Sum an array of 64-bit integers
section .data
array dq 10, 20, 30, 40, 50
length equ 5
section .text
xor rax, rax ; sum = 0
mov rcx, length ; counter
lea rbx, [array] ; pointer to array
.loop:
add rax, [rbx] ; sum += array[i]
add rbx, 8 ; advance to next element
dec rcx
jnz .loop
; RAX = 150
Nested Loops
; Process a 5x5 matrix
mov rcx, 5 ; outer loop counter
.outer:
mov rdx, 5 ; inner loop counter
.inner:
; Process element
; ... instructions ...
dec rdx
jnz .inner ; Inner loop
dec rcx
jnz .outer ; Outer loop
; Warning: nested loops can overflow RCX-based counting
; Use separate registers or stack for counters
Loop Unrolling
; Manual loop unrolling (trading code size for speed)
; Instead of 4 iterations:
mov rcx, 1000 / 4 ; Number of unrolled iterations
.loop:
; Iteration 1
add rax, [rbx]
add rbx, 8
; Iteration 2
add rax, [rbx]
add rbx, 8
; Iteration 3
add rax, [rbx]
add rbx, 8
; Iteration 4
add rax, [rbx]
add rbx, 8
dec rcx
jnz .loop
; Handle remaining elements with a cleanup loop
Common Mistakes
1. Off-by-one errors
Compare correctly: jl for <, jle for <=, je for ==.
2. RCX overwritten in loop body
If the loop body calls functions, RCX might be modified. Save and restore RCX.
3. Infinite loops
Missing increment/decrement or wrong condition causes infinite loops.
4. LOOP instruction performance
Don't use the loop instruction in performance-critical code. Manual dec/jnz is faster.
5. Not checking for empty loops
If iteration count is 0, ensure the body doesn't execute. Add a check before the loop.
Practice Questions
1. How do you implement a for loop in assembly? Initialize counter, check condition, execute body, increment/decrement counter, jump back.
2. Why is counting down preferred? Comparing RCX to zero (dec rcx; jnz) is simpler than comparing to a non-zero value each iteration.
3. What is loop unrolling? Repeating the loop body multiple times per iteration to reduce loop overhead (dec/jnz calls).
Challenge: Write a loop that finds the maximum value in an array of 64-bit integers.
FAQ
{{< faq question="Is the LOOP instruction useful?" >} Rarely. LOOP is slow on modern CPUs. Use dec rcx; jnz instead for better performance. {{< /faq >}}
{{< faq question="How many loops can I nest?" >} Unlimited, but limited by available registers. Save counters to stack or memory for deep nesting. {{< /faq >}}
{{< faq question="Can I loop without a counter?" >} Yes. Use sentinel values (like null terminator in strings) or condition-based loop termination. {{< /faq >}}
{{< faq question="What is Duff's device?" >} A loop-unrolling technique from C that mixes switch and while. Rare in assembly. {{< /faq >}}
{{< faq question="Should I always unroll loops?" >} No. Unrolling increases code size. Modern CPUs with branch predictors handle tight loops well. {{< /faq >}}
Mini Project
Implement array sum with a counted loop:
section .data
array dq 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
length equ 10
section .text
global array_sum
; long array_sum(long *arr, long count)
; Args: RDI=array, RSI=count
array_sum:
xor rax, rax ; sum = 0
xor rcx, rcx ; i = 0
.loop:
cmp rcx, rsi
jge .done
add rax, [rdi + rcx*8]
inc rcx
jmp .loop
.done:
ret
What's Next
Now that you understand loops, explore conditions and branching in more detail.
| Topic | Description | Link |
|---|---|---|
| Assembly Conditions | Conditional execution | {{< ref "07-conditions" >}} |
| Assembly Procedures | Function calls | {{< ref "10-procedures" >}} |
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro