4.2.3. LDR and STR (post-indexed immediate offset)

Load and Store register. Byte and halfword loads are zero-extended or sign-extended to 32 bits.


op{type}{T}{cond} Rd, {Rd2,} [Rn], #offset



can be any one of:


Load Register


Store Register.


can be any one of:


unsigned Byte


Signed Byte (LDR only)


unsigned Halfword


Signed Halfword (LDR only)


omitted, for Word




is an optional suffix. If T is present, the memory system treats the access as though the processor was in User mode, even if it is in a privileged mode (see Processor mode). T has no effect in User mode.


is an optional condition code (see Conditional execution).


is the ARM register to load or save.


is the second ARM register to load or save (type == D only).


is the register on which the memory address is based. Rn must not be the same register as Rd or Rd2.


is an immediate offset. If offset is omitted, the instruction is a zero offset instruction.

Operation and restrictions

The value in Rn is used as the memory address for the transfer. The offset is applied to the value in Rn after the data transfer takes place. The result is written back into Rn.

The range of offsets allowed is:

  • –4095 to +4095 for ARM Word or Byte instructions.

  • –255 to +255 for ARM Signed Byte, Halfword, Signed Halfword, and Doubleword instructions.

  • –255 to +255 for all Thumb-2 instructions except Doubleword instructions.

  • –1020 to +1020 for Thumb-2 Doubleword instructions. Must be a multiple of 4.

The T suffix is not available for Thumb-2 instructions, or for ARM doubleword instructions. It is available for all other ARM instructions.

Doubleword register restrictions

For Thumb-2 instructions, you must not specify r15 for either Rd or Rd2.

For ARM instructions:

  • Rd must be an even-numbered register

  • Rd must not be r14

  • Rd2 must be R(d + 1).

Loading to r15

Rd can be the PC, in either ARM or Thumb-2 code. In this case, type must be omitted.

A load to r15 (pc) causes a branch to the instruction at the address loaded.

In ARMv4, bits[1:0] of the value loaded must be zero.

In ARMv5 and above:

  • bits[1:0] of a value loaded to r15 must not have the value 0b10

  • if bit[0] of a value loaded to r15 is set, the processor changes to Thumb state.

You cannot use the T suffix when loading to r15.

Saving from r15

In Thumb code, you cannot save from r15.

In ARM code, avoid saving from r15 if possible.

If you do save from r15, the value saved is the address of the current instruction, plus an implementation-defined constant. The constant is always the same for a particular processor.

If your assembled code might be used on different processors, you can find out what the constant is at runtime using code like the following:

    SUB R1, PC, #4 ; R1 = address of following STR instruction
    STR PC, [R0]   ; Store address of STR instruction + offset,
    LDR R0, [R0]   ; then reload it
    SUB R0, R0, R1 ; Calculate the offset as the difference

If your code is to be assembled for a particular processor, the value of the constant is available in armasm as {PCSTOREOFFSET}.


These ARM instructions are available in all versions of the ARM architecture.

These 32-bit Thumb-2 instructions are available in all T2 variants of the ARM architecture.

There are no 16-bit versions of these instructions.

The LDRSHT, LDRHT, STRHT, and LDRSBT instructions are only available in T2 variants of ARMv6.

In T and T2 variants of ARMv5 and above:

  • in ARM state, a load to r15 causes a change to Thumb state if bit[0] of the value loaded is 1

  • in Thumb state, a load to r15 causes a change to ARM state if bit[0] of the value loaded is 0.

Copyright © 2002-2005 ARM Limited. All rights reserved.ARM DUI 0204F