Control Flow
Loops
Implementing while loops and for loops with branches.
Loops in Assembly
There's no for or while in assembly. We build loops with:
Counting Loop Pattern
Here's the classic "count down to zero" loop:
.ORIG x3000
AND R0, R0, #0 ; R0 = sum = 0
AND R1, R1, #0
ADD R1, R1, #5 ; R1 = counter = 5
LOOP
ADD R1, R1, #0 ; Set CC for R1
BRz DONE ; If counter == 0, exit loop
ADD R0, R0, R1 ; sum += counter
ADD R1, R1, #-1 ; counter--
BR LOOP ; Go back to top
DONE HALT ; R0 = 5+4+3+2+1 = 15
.ENDIterating Over an Array
Combine a pointer register with a counter to walk through data:
.ORIG x3000
; Sum 5 numbers starting at ARRAY
AND R0, R0, #0 ; R0 = sum
LEA R1, ARRAY ; R1 = pointer to current element
AND R2, R2, #0
ADD R2, R2, #5 ; R2 = count
LOOP
ADD R2, R2, #0 ; Check counter
BRz DONE
LDR R3, R1, #0 ; R3 = current element
ADD R0, R0, R3 ; sum += element
ADD R1, R1, #1 ; pointer++
ADD R2, R2, #-1 ; count--
BR LOOP
DONE HALT
ARRAY .FILL #3
.FILL #7
.FILL #1
.FILL #4
.FILL #5
.ENDThe pattern ADD R2, R2, #0 is a common idiom — it doesn't change R2 but sets the condition codes so we can branch on its value.
Loop Templates
Most loops in LC-3 follow one of these templates:
Count-down loop (when you know how many iterations): ``
AND counter, counter, #0
ADD counter, counter, #N
LOOP
ADD counter, counter, #0
BRz DONE
; ... body ...
ADD counter, counter, #-1
BR LOOP
DONE
`
Pointer-walk loop (for strings and arrays):
`
LEA ptr, DATA ; or LD ptr, ADDR
LOOP
LDR char, ptr, #0
BRz DONE ; null terminator = stop
; ... process char ...
ADD ptr, ptr, #1
BR LOOP
DONE
`
Sentinel loop (stop when a condition is met):
`
LOOP
; ... do something ...
; ... compute a condition ...
BRz DONE ; or BRn, BRp depending on your stop condition
BR LOOP
DONE
``
Recognize which template fits your problem, then fill in the body.
Exercise
Write a program that counts down from 9 to 1, printing each digit. Output should be "987654321".
main.asm
1
R0
x00000
R1
x00000
R2
x00000
R3
x00000
R4
x00000
R5
x00000
R6
x00000
R7
x00000
PCx3000
CC
NZP