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:
Passw3 addedNew w1New w3
1112
2233
3364

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 formMeaning after cmp left, right
b .LABELAlways branch
beq .LABELBranch if left == right
bne .LABELBranch if left != right
blt .LABELBranch if left < right
ble .LABELBranch if left <= right
bgt .LABELBranch if left > right
bge .LABELBranch 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.

  1. Without a branch, how does execution move through instructions?
  2. After cmp w4, w5, when does bge .READY branch?
  3. Translate this sequence into one C-style condition:
    cmp w2, 0
    ble .END
  4. How many times does the body run if w3 starts at 4, the body subtracts 1, and ble .END exits when w3 <= 0?
  5. Assume x6 = 0x800. Which address does ldr w1, [x6, 8] read, and why is the destination w1 rather than x1?

Answers

Show the answers
  1. The program counter advances execution to the next instruction in memory.
  2. It branches when the signed value in w4 is greater than or equal to the signed value in w5.
  3. The branch reaches .END when w2 <= 0. If this is a loop exit, the loop body continues while w2 > 0.
  4. Four times. The body runs with starting values 4, 3, 2, and 1; the next test sees 0 and exits.
  5. It reads address 0x808. x6 holds the 64-bit address, while w1 receives one 32-bit int.

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.