Immediate Addressing

The address is included directly in the instruction (through a label):

LDR R0, some_label

Register Indirect Addressing

The address is held in a register:

LDR R0, [R2]

R0 will receive the value at the address held in R2. The address can be loaded into R2 using ADR:

ADR R2, some_label

Immediate Offset Addressing

This is similar to Register Indirect Addressing, but includes a constant offset:

LDR R0, [R1, #8]

The offset value can be negative, but is limited to 12 bits (~2KB)

Register Offset Addressing

This is similar to Immediate Offset Addressing but uses the value in a register as the offset:

LDR R0, [R1, R2]

This can be a negative offset:

LDR R0, [R1, -R2]

Post-Indexed Indirect Addressing

Sometimes, it may be helpful to update the address in the register to reflect the offset applied.

LDR R0, [R1],#4

In this example, R0 will receive the value at the address stored in R1, then R1 will be incremented by 4. Registers can be used in place of literals for the offset as in Register Offset Addressing

Pre-Indexed Indirect Addressing

This is similar to Post-Indexed Indirect Addressing but updates the value in the address register to reflect the offset before applying it to the instruction:

LDR R0, [R1, #4]!

Here, R1 will be incremented by 4, then R0 will receive the value at the updated address stored in R1.