Memory: Loads, Stores & Addressing Modes

ldr/str in all sizes, base + offset, scaled register offsets, pre/post-indexing, and ldp/stp.

Everything in memory — arrays, structs, the stack, peripheral registers — is reached with loads and stores. ARM's addressing modes let one instruction compute the address, access memory and update the pointer.

Walking arrays and strings

ldrsw x3, [x0], #4 loads a signed 32-bit int from the address in x0, then adds 4 to x0 (post-index).

subs sets the flags; b.ne loops until the counter reaches zero.

ldr w0, [x0, x1, lsl #2] reads a[i]: the address is x0 + x1*4, computed inside the instruction.

ldp/stp move a pair of registers, here swapping two longs.

ldrb loads a single byte, zero-extended to 32 bits.

Addressing modes

ldr w0, [x0, x1] // a is an int array, x1 the index ldr w0, [x0, x1, lsl #2]

The index must be scaled by the element size (4 bytes for int); without lsl #2 it reads from the wrong address.

What is the difference between [x0, #8]! and [x0], #8?

Pre-index: x0 is increased by 8 first and the new address is used. Post-index: the old address is used and x0 is increased afterwards.