From ARMwiki
(Difference between revisions)
Jump to: navigation, search

Revision as of 02:00, 12 December 2011

Instruction LDM[IA¦IB¦DA¦DB (¦FD¦ED¦FA¦EA)]
Function Load Multiple
Category Load and Store
ARM family All
Notes -



LDM, for Load Multiple, is a way of reading memory contents into multiple registers in one single instruction. It is useful as both a way to quickly unstack registers on exit from a subroutine, or in combination with Store Multiple as a way to produce block copies capable of saturating the memory bus (in other words, about as fast as the hardware can manage).

LDM also includes (optional) writeback to the base address, so all stack or store offset calculations can be performed automatically.

LDM will load registers - any subset between one and all of the general purpose R0-R15 registers. This is normally the register set visible to the current processor mode, however (using the ^ suffix) it is possible to access the banked (User) registers while the processor is in a privileged mode.

The registers are read in sequence, with the lowest numbered register being read from the lowest memory address, being read in order.


  LDM[cond][type]  Rn[!], {<regs>}[^]

Where '!' specifies to write back the updated base pointer to the base register,
and '^' specifies to access the banked registers (32 bit).

The <regs> can be a comma-separated list, or a dashed range, or a mixture. For example:

  R0, R1, R2, R3, R4, R7, R8
  R0-R4, R7, R8


 Read multiple registers from memory.

Types of memory access

LDM provides four different types of access:

  • Increment After
  • Increment Before
  • Decrement After
  • Decrement Before

Please refer to the documentation for STM for specifics.

Alternative memory access names

In order to facilitate stack based usage, there are alternative names which are more useful for stack operations:

  • Fully Descending
  • Fully Ascending
  • Empty Descending
  • Empty Ascending

Please refer to the documentation for STM for specifics.

RISC OS and ARM Linux both use Fully Descending stacks, which grow down from the highest address, and the stack pointer pointing to the last used location.


Please refer to the documentation for STM for an example of wrapping a function with stacked registers, and using LDM/STM to implement a fast block copy routine.


  • The S bit, controlled by the ^ suffix controls whether or not privileged modes will force loading the banked (user mode) registers instead of those applicable to the current mode. Accordingly, doing this in User (or System) mode is unpredictable.
  • If S bit is specified, the base register is always the current mode register, not the banked version.
  • If S bit is specified, the following instruction should not touch banked registers. It is good practice to use a NOP after such an instruction.
  • On 26 bit architectures, using ^ with PC in the last of registers to load would have the side effect of writing the processor flags in addition to the return address. This was a nifty way to have a complete function exit on one single instruction. This should not be used in 32 bit architectures.
  • R15 as a base register, is unpredictable. As a register to load, will be loaded with the value present written to the Program Counter; thus pushing R14 and reading it back into PC may be used to exit the function in the LDM instruction.
  • If the base register is specified in the register list, and writeback is enabled, then things could go bang!. Just, don't.
  • Addresses should be word-aligned.


The instruction bit pattern is as follows:

31 - 28 27 - 25 24 23 22 21 20 19 - 16 15 - 0
condition 1 0 0 P U S W 1 Rn (base) Bitmask of registers


  • P specifies if the address is incremented before the data is read (P=1) or incremented after (P=0).
  • U specifies if the address is ascending (U=1) or descending (U=0).
  • S specifies if banked register access should occur when in privileged modes [or if R15 and 26 bit and user mode, if the PSR should be written while PC is updated]
  • W specifies if the base register address should be updated after the data transfer.
Personal tools