ldm

Load Multiple (A32)

LDM<mode><c> <Rn>{!}, <registers>

Loads multiple registers from memory (Stack pop).

Pseudocode Operation

address ← Rn
if P == 1 and U == 1 then
  address ← address + 4
for each register in register_list (in ascending order)
  register ← memory[address]
  address ← address + 4
if P == 1 and U == 0 then
  address ← address - 4
if W == 1 then
  Rn ← address
if S == 1 then
  CPSR ← SPSR (if loading PC in privileged mode)
condition_flags unchanged

Example

LDMia r1!, registers

Encoding

Binary Layout
cond
31:28
100
27:25
0
24
0
23
0
22
W
21
1
20
Rn
19:16
register_list
15:0
 
Format Load Multiple
Opcode 0x08100000
Extension A32 (Base)

Operands

  • Rn
    First source / base general-purpose register
  • registers
    List

Related

Other forms of ldm

  • ldm Load Multiple (Thumb)

More in A32 (Base)

Reference

Instruction Forms

Encoding Instruction ISA Bit pattern
0x08900000 LDM{IA}{<c>}{<q>} <Rn>{!}, <registers> A32 cond | 100 | 0 | 1 | 0 | W | 1 | Rn | register_list
0xC800 LDM{IA}{<c>}{<q>} <Rn>{!}, <registers> T32 1100 | 1 | Rn | register_list
0xE8900000 LDM{IA}{<c>}.W <Rn>{!}, <registers> T32 1110100 | 01 | 0 | W | 1 | Rn | P | M | register_list
0x08508000 LDM{<amode>}{<c>}{<q>} <Rn>{!}, <registers_with_pc>^ A32 cond | 100 | P | U | 1 | W | 1 | Rn | 1 | register_list
0x08500000 LDM{<amode>}{<c>}{<q>} <Rn>, <registers_without_pc>^ A32 cond | 100 | P | U | 1 | 0 | 1 | Rn | 0 | register_list
0x08100000 LDMDA{<c>}{<q>} <Rn>{!}, <registers> A32 cond | 100 | 0 | 0 | 0 | W | 1 | Rn | register_list
0x09100000 LDMDB{<c>}{<q>} <Rn>{!}, <registers> A32 cond | 100 | 1 | 0 | 0 | W | 1 | Rn | register_list
0xE9100000 LDMDB{<c>}{<q>} <Rn>{!}, <registers> T32 1110100 | 10 | 0 | W | 1 | Rn | P | M | register_list
0x09900000 LDMIB{<c>}{<q>} <Rn>{!}, <registers> A32 cond | 100 | 1 | 1 | 0 | W | 1 | Rn | register_list

Description

Load Multiple Decrement After (Full Ascending) loads multiple registers from consecutive memory locations using an address from a base register. The consecutive memory locations end at this address, and the address just below the lowest of those locations can optionally be written back to the base register. The lowest-numbered register is loaded from the lowest memory address, through to the highest-numbered register from the highest memory address. See also Encoding of lists of general-purpose registers and the PC. Armv8.2 permits the deprecation of some Load Multiple ordering behaviors in AArch32 state, for more information see FEAT_LSMAOC. The registers loaded can include the PC, causing a branch to a loaded address. This is an interworking branch, see Pseudocode description of operations on the AArch32 general-purpose registers and the PC. Related system instructions are LDM (User registers) and LDM (exception return).

Operation

if ConditionPassed() then
    EncodingSpecificOperations();
    address = R[n] - 4*BitCount(registers) + 4;
    for i = 0 to 14
        if registers<i> == '1' then
            R[i] = MemS[address,4];  address = address + 4;
    if registers<15> == '1' then
        LoadWritePC(MemS[address,4]);
    if wback && registers<n> == '0' then R[n] = R[n] - 4*BitCount(registers);
    if wback && registers<n> == '1' then R[n] = bits(32) UNKNOWN;