| |||
| Home > Writing ARM and Thumb Assembly Language > Load and store multiple register instructions > Thumb LDM and STM instructions | |||
The Thumb instruction set contains the following pairs of multiple-register transfer instructions:
LDM and STM for
block memory transfers
PUSH and POP for stack
operations.
These instructions can be used to load or store any subset
of the low registers from or to memory. The base register is always
updated at the end of the multiple register transfer instruction.
You must specify the ! character. The only valid
suffix for these instructions is IA.
Examples of these instructions are:
LDMIA r1!, {r0,r2-r7}
STMIA r4!, {r0-r3}
These instructions can be used to push any subset of the low registers and (optionally) the link register onto the stack, and to pop any subset of the low registers and (optionally) the pc off the stack. The base address of the stack is held in r13. Examples of these instructions are:
PUSH {r0-r3}
POP {r0-r3}
PUSH {r4-r7,lr}
POP {r4-r7,pc}
The optional addition of the lr or pc to the register list provides support for subroutine entry and exit.
The stack is always full descending.
The block copy example, Example 2.11, can be converted into Thumb instructions (see Example 2.13).
Because the Thumb LDM and STM instructions
can access only the low registers, the number of words copied per
iteration is reduced from eight to four. In addition, the LDM and STM instructions
can be used to carry out the single word at a time copy, because
they update the base pointer after each access. If LDR and STR were
used for this, separate ADD instructions would be required
to update each base pointer.
Example 2.13.
AREA Tblock, CODE, READONLY ; Name this block of code
num EQU 20 ; Set number of words to be copied
ENTRY ; Mark first instruction to execute
header ; The first instruction to call
MOV sp, #0x400 ; Set up stack pointer (r13)
ADR r0, start + 1 ; Processor starts in ARM state,
BX r0 ; so small ARM code header used
; to call Thumb main program
CODE16 ; Subsequent instructions are Thumb
start
LDR r0, =src ; r0 =pointer to source block
LDR r1, =dst ; r1 =pointer to destination block
MOV r2, #num ; r2 =number of words to copy
blockcopy
LSR r3,r2, #2 ; Number of four word multiples
BEQ copywords ; Less than four words to move?
PUSH {r4-r7} ; Save some working registers
quadcopy
LDMIA r0!, {r4-r7} ; Load 4 words from the source
STMIA r1!, {r4-r7} ; and put them at the destination
SUB r3, #1 ; Decrement the counter
BNE quadcopy ; ... copy more
POP {r4-r7} ; Don't need these now-restore originals
copywords
MOV r3, #3 ; Bottom two bits represent number
AND r2, r3 ; ...of odd words left to copy
BEQ stop ; No words left to copy?
wordcopy
LDMIA r0!, {r3} ; load a word from the source and
STMIA r1!, {r3} ; store it to the destination
SUB r2, #1 ; Decrement the counter
BNE wordcopy ; ... copy more
stop MOV pc, lr ; Return to caller
AREA BlockData, DATA, READWRITE
src DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
END