stm

Store Multiple (A32)

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

Stores multiple registers to memory.

Details

Store Multiple stores the registers specified in the register list to consecutive memory addresses starting from the address in Rn. The addressing mode (IA, DB, DA, ED) is encoded in the P and U bits; when W=1, Rn is updated to point past the last stored word. No condition flags are modified. This instruction is available in A32 and includes optional privilege level adjustments when storing the program counter.

Pseudocode Operation

address ← Rn;
if P then address ← address + 4 * NumberOfRegisters(); endif;
for i = 0 to 15 do
  if register_list[i] == 1 then
    if U then
      Memory[address] ← Ri;
      address ← address + 4;
    else
      address ← address - 4;
      Memory[address] ← Ri;
    endif;
  endif;
endfor;
if W then Rn ← address; endif;

Example

STMia r1!, registers

Encoding

Binary Layout
cond
100
0
0
0
W
0
Rn
register_list
 
Format Store Multiple
Opcode 0x08000000
Extension A32 (Base)

Operands

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

Reference (Arm AArch32 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x08800000 STM{IA}{<c>}{<q>} <Rn>{!}, <registers> A32 cond | 100 | 0 | 1 | 0 | W | 0 | Rn | register_list
0xC000 STM{IA}{<c>}{<q>} <Rn>!, <registers> T32 1100 | 0 | Rn | register_list
0xE8800000 STM{IA}{<c>}.W <Rn>{!}, <registers> T32 1110100 | 01 | 0 | W | 0 | Rn | 0 | M | register_list
0x08400000 STM{<amode>}{<c>}{<q>} <Rn>, <registers>^ A32 cond | 100 | P | U | 1 | 0 | 0 | Rn | register_list
0x08000000 STMDA{<c>}{<q>} <Rn>{!}, <registers> A32 cond | 100 | 0 | 0 | 0 | W | 0 | Rn | register_list
0x09000000 STMDB{<c>}{<q>} <Rn>{!}, <registers> A32 cond | 100 | 1 | 0 | 0 | W | 0 | Rn | register_list
0xE9000000 STMDB{<c>}{<q>} <Rn>{!}, <registers> T32 1110100 | 10 | 0 | W | 0 | Rn | 0 | M | register_list
0x09800000 STMIB{<c>}{<q>} <Rn>{!}, <registers> A32 cond | 100 | 1 | 1 | 0 | W | 0 | Rn | register_list

Description

Store Multiple Decrement After (Empty Descending) stores multiple registers to 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 Store Multiple ordering behaviors in AArch32 state, for more information see FEAT_LSMAOC. For details of related system instructions see STM (User registers).

Operation

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