2.8.5. Thumb LDM and STM instructions

The Thumb instruction set contains two pairs of multiple-register transfer instructions:

LDM and STM

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}

PUSH and POP

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.

Thumb-state block copy example

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     r0, #0x18                ; angel_SWIreason_ReportException
        LDR     r1, =0x20026             ; ADP_Stopped_ApplicationExit
        SWI     0xAB                     ; Thumb semihosting SWI
        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
Copyright © 2000, 2001 ARM Limited. All rights reserved.ARM DUI 0068B
Non-Confidential