5.7.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/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 5.10, can be converted into Thumb instructions. An example conversion can be found as tblock.s in the examples\asm subdirectory of the toolkit.

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/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/STR were used for this, separate ADD instructions would be required to update each base pointer.

Example 5.12. 

		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						; Angel semihosting Thumb 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 © 1997, 1998 ARM Limited. All rights reserved.ARM DUI 0040D
Non-Confidential