CSSE 132 Post-Homework Review
Homework 2 Review + Solutions: ARM64 Data and Loops
Use this page after Homework 2 to compare your approach with a worked one. It is an exam-review resource, not a replacement for doing the assignment yourself.
What Homework 2 Practiced
HW02 connects C function calls to ARM64: integer arguments and results use w registers, addresses use x registers, and ldr/str move 4-byte int values between a register and memory. Its four functions also practice loops made from cmp, branches, and ret.
The Register Rule That Prevents Many Bugs
| Kind of value | Use | Example |
|---|---|---|
| 32-bit integer | w0–wN | array element, length, sum, or result |
| 64-bit address / pointer | x0–xN | base address of an int array |
| Function arguments | w0/x0, then w1/x1 | swap(int *a, int *b) receives addresses in x0, x1 |
| Return value | w0 for an int | mult places its product in w0 |
Same numbered register, different width: w0 is the low 32 bits of x0. Writing w0 clears the top 32 bits of x0. Do not store an address in w0: an int * belongs in an x register, while an int loaded from it belongs in a w register.
Follow the Value, Not Just the Instruction
Memory → register
ldr w2, [x0]x0 is an address. Read the 4-byte int stored there into w2.
Register → memory
str w2, [x0]Write the 4-byte value in w2 to the location whose address is in x0.
Move through an int array
add x0, x0, 4Each int is 4 bytes, so this advances from array[i] to array[i + 1].
Common mistake: brackets matter. [x0] means “the memory at this address.”
Worked Walkthroughs
swap(int *a, int *b)
Core idea: preserve both old values before either location is overwritten: temp = *a; *a = *b; *b = temp;.
swap:
ldr w2, [x0] // w2 = *a
ldr w3, [x1] // w3 = *b
str w3, [x0] // *a = old *b
str w2, [x1] // *b = old *a
retx0 and x1 stay as addresses; w2 and w3 hold the values. Loading both values first prevents the original *a from being lost.
mult(int x, int y)
Core idea: multiplication is repeated addition. Since y is non-negative, add x until a counter reaches y.
mult:
mov w2, 0 // count = 0
mov w3, 0 // total = 0
.mult_loop:
cmp w2, w1
beq .mult_done
add w3, w3, w0 // total += x
add w2, w2, 1 // count++
b .mult_loop
.mult_done:
mov w0, w3 // return total
retFor mult(-2, 3), totals are 0, -2, -4, -6. Do not use mul; this homework explicitly forbids it.
if_zero(int *a, int len)
Core idea: inspect one item at a time, stopping when a zero is found or the length reaches zero.
if_zero:
.if_zero_loop:
cmp w1, 0
beq .no_zero
ldr w2, [x0]
cmp w2, 0
beq .found_zero
add x0, x0, 4
sub w1, w1, 1
b .if_zero_loop
.found_zero:
mov w0, 1
ret
.no_zero:
mov w0, 0
retTest len before ldr; otherwise the scan can read past the array. The pointer advances by 4 because each element is an int.
find_zero(int *a, int len)
Core idea: this scan returns an index rather than a yes/no result. An index changes by 1; an int byte offset changes by 4.
find_zero:
mov w2, 0 // index = 0
mov x3, 0 // byte offset = 0
.find_zero_loop:
ldr w4, [x0, x3]
cmp w4, 0
beq .find_zero_done
add w2, w2, 1
add x3, x3, 4
b .find_zero_loop
.find_zero_done:
mov w0, w2
retThe homework guarantees a zero exists. Advancing x3 by 1 would read successive bytes instead of successive ints.
Test, Debug, and Submit
- On the VM, edit only
problems.sin the Homework 2 directory. - Run
make cleanfor “file format not recognized,” then runmake test_asm(ormake) and./test_asm. - If you get
Segmentation fault, inspect everyldr/str: is the base anxaddress register, are brackets present, and did the pointer stay within the array? - Submit only after
git add problems.s,git commit,git push, then pulling that commit into the local clone and uploading the correctproblems.sto Gradescope.
Common HW02 Mistakes
wNAddresses need
xN.An
int array advances 4 bytes per element.Tests read an
int result from w0.Labels are file-wide; use distinct names in every function.
Check Yourself
- Why does
ldr w2, [x0]usew2butx0? - After three array iterations, what byte offset reaches the fourth
int? - Where must an ARM function place an
intresult beforeret?
Answers
The loaded item is a 32-bit int, while the base is a 64-bit address. The offset is 12 bytes. The return value goes in w0.