CSSE 132 Mini-reading
ARM64 Control Flow in 10 Minutes
Review how the program counter, labels, comparisons, and branches turn straight-line ARM64 instructions into decisions and loops.
Why This Matters
Branches let assembly implement the decisions and repetition that you write
as if statements and loops in C. In CSSE 132, you will trace those
branches, translate short ARM64 sequences into pseudocode, and combine control
flow with loads and stores to process arrays.
Core Idea
The special program counter, written pc, tracks
the instruction being executed. ARM64 instructions occupy 4 bytes, so
straight-line execution advances from one instruction address to the address 4
bytes later. A branch changes that path by sending execution to a named location
called a label.
Unconditional branch
b .LOOP
Execution always continues at .LOOP. The label marks a location;
it does not perform an operation by itself.
Conditional branch
cmp w0, w1
ble .DONE
cmp compares the two 32-bit data values. ble branches
only when w0 <= w1.
cmp w0, w1 behaves like calculating w0 - w1 for the
condition flags, but it does not store the subtraction result. The following
conditional branch reads those flags. Keep the comparison and branch together
when you translate the code.
Use wN registers for the 32-bit int values in these
examples. Use xN registers for 64-bit addresses. For example,
ldr w3, [x0] loads one 32-bit value from the address in
x0.
Worked Examples
Example 1: Decide whether a branch is taken
Assume w0 = 7 and w1 = 9.
cmp w0, w1
ble .SMALLER_OR_EQUAL
mov w2, 1
.SMALLER_OR_EQUAL:
The comparison asks whether 7 is less than or equal to 9. It is, so
ble branches to the label and skips mov w2, 1. This
example does not change w2.
Example 2: Recognize a while loop
mov w3, 3
.LOOP:
cmp w3, 0
ble .ENDLOOP
sub w3, w3, 1
b .LOOP
.ENDLOOP:
Read the code by following the possible paths. At the top of each pass,
ble exits when w3 <= 0. Otherwise, the body subtracts
1 and the unconditional branch returns to the test.
int value = 3;
while (value > 0) {
value = value - 1;
}
The test uses the opposite of the C loop condition because the branch leaves the loop. Starting from 3, the body runs three times and the final value is 0.
Example 3: Trace values one pass at a time
mov w1, 0
mov w3, 1
.LOOP:
cmp w3, 4
bge .DONE
add w1, w1, w3
add w3, w3, 1
b .LOOP
.DONE:
| Pass | w3 added | New w1 | New w3 |
|---|---|---|---|
| 1 | 1 | 1 | 2 |
| 2 | 2 | 3 | 3 |
| 3 | 3 | 6 | 4 |
On the next test, w3 >= 4, so the branch reaches
.DONE. The final values are w1 = 6 and
w3 = 4.
Example 4: Swap two array entries
Assume x4 holds the address of a two-element int
array. Each entry occupies 4 bytes.
ldr w1, [x4]
ldr w2, [x4, 4]
str w1, [x4, 4]
str w2, [x4]
The loads save both original values before either memory location changes.
The stores then write the first value to the second entry and the second value
to the first. The offset 4 selects the next int, not the fourth
array entry.
Example 5: Walk through an array
Assume x0 starts at an array of four int values and
w2 is a running count.
mov w1, 0
mov w2, 0
.LOOP:
cmp w1, 4
bge .ENDLOOP
ldr w3, [x0]
cmp w3, 0
ble .NOT_POSITIVE
add w2, w2, 1
.NOT_POSITIVE:
add w1, w1, 1
add x0, x0, 4
b .LOOP
.ENDLOOP:
w1 counts entries, while x0 advances by 4 bytes to
the next address. If the array is [-2, 5, 0, 7], only 5 and 7 pass
the positive-value test, so the final count in w2 is 2.
Common Mistakes
Reversing the comparison
cmp w0, w1 followed by ble tests
w0 <= w1. Operand order matters.
Translating the exit test directly
If ble .ENDLOOP leaves the loop when x <= 0, the C
loop continues while x > 0.
Tracing labels as instructions
A label names a location. Move to its following instruction without changing any register or memory value.
Using 32-bit registers for addresses
ARM64 addresses belong in xN registers. Load or store a 32-bit
int through that address with a wN register.
Quick Reference
| Course form | Meaning after cmp left, right |
|---|---|
b .LABEL | Always branch |
beq .LABEL | Branch if left == right |
bne .LABEL | Branch if left != right |
blt .LABEL | Branch if left < right |
ble .LABEL | Branch if left <= right |
bgt .LABEL | Branch if left > right |
bge .LABEL | Branch if left >= right |
Array reminder: a 32-bit int occupies 4 bytes,
so advancing to the next entry adds 4 to the 64-bit address register.
Check Yourself
Try these before opening the answers. The values differ from Worksheet 05.
- Without a branch, how does execution move through instructions?
- After
cmp w4, w5, when doesbge .READYbranch? - Translate this sequence into one C-style condition:
cmp w2, 0ble .END - How many times does the body run if
w3starts at 4, the body subtracts 1, andble .ENDexits whenw3 <= 0? - Assume
x6 = 0x800. Which address doesldr w1, [x6, 8]read, and why is the destinationw1rather thanx1?
Answers
Show the answers
- The program counter advances execution to the next instruction in memory.
- It branches when the signed value in
w4is greater than or equal to the signed value inw5. - The branch reaches
.ENDwhenw2 <= 0. If this is a loop exit, the loop body continues whilew2 > 0. - Four times. The body runs with starting values 4, 3, 2, and 1; the next test sees 0 and exits.
- It reads address
0x808.x6holds the 64-bit address, whilew1receives one 32-bitint.
Next Step
Complete Worksheet 05: Assembly II. For each loop, write the exit condition beside the conditional branch, then trace one row per pass until that condition becomes true.