Loading and Storing
To load the value stored in r0
into r1
, we do this:
ldr r1, r0
But to load the data in the address stored in r0
, we can do this instead.
ldr r1, [r0]
The square brackets indicate that we access the value at the address stored.
To store a value from r2
to the address in r3
, we can do this.
str r2, [r3]
Offsets
Very often you will want to access a location that is at a fixed distance from a base pointer or that is computed from another register. ARM gives you several addressing modes for this.
Immediate offsetsÂ
str r2, [r1, #2] @ offset: [r1+2] = r2 (r1 unchanged)
str r2, [r1, #4]! @ pre-indexed: [r1+4] = r2 (r1 = r1+4)
ldr r3, [r1], #4 @ post-indexed: r3 = [r1] (r1 = r1+4)
Register offsets
str r2, [r1, r3] @ address = r1 + r3
Scaled register offsets
str r2, [r1, r3, LSL #2] @ offset = r3 << 2 (multiply by 4)
str r2, [r1, r3, LSL #2]! @ pre-indexed (updates r1)
ldr r4, [r1], r3, LSL #2 @ post-indexed
Multiple Read and Writes
You can also use the instructions ldm
and stm
to load/store multiple values to registers at the same time. ldmia
increments after the first is loaded, but ldmib
increments before. ldmda
and ldmdb
do the same but decrement.
ldmia r0, {r3-r6} @ load four words: r3 r4 r5 r6 to [r0 … r0+12]
stmdb r1, {r2-r4} @ store three words: r2 r3 r4 to [r1-12 … r1-4] and r1 = r1-12
Stack Handling
The push
instruction decreases the sp
by 4 bytes, before storing the info to the new address.
push {r0}
pop
is the reverse, as the value in the SP address is loaded to a register, and the sp
increases by 4 bytes.
pop {r0}
Conditional execution
The cmp
code subtracts its second operand from the first, discards the result, and updates the CPSR flags. These flags can then be used by condition codes to provide conditional execution, such as loops using the b
code.
Code | Meaning | Trigger |
---|---|---|
eq | equal / zero | Z = 1 |
ne | not equal | Z = 0 |
cs / hs | carry set / unsigned ≥ | C = 1 |
cc / lo | carry clear / unsigned < | C = 0 |
mi | minus | N = 1 |
pl | plus | N = 0 |
vs | overflow set | V = 1 |
vc | overflow clear | V = 0 |
loop:
ldr r0, [r1], #4
cmp r0, #0 @ set Z if element == 0
beq done @ branch equal → element was zero
b loop @ otherwise keep scanning
done: