5.7.4. Block copy with LDM and STM

Example 5.10 is an ARM code routine that copies a set of words from a source location to a destination by copying a single word at a time. It is supplied as word.s in the examples\asm subdirectory of the toolkit. Refer to Code examples for instructions on how to assemble, link, and execute the example.

Example 5.10. : Block copy

			AREA 		Word, CODE, READONLY						; name this block of code.
num			EQU		20						; set number of words to be copied.
			ENTRY								; mark the first instruction to call
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
wordcopy			LDR		r3, [r0], #4						; load a word from the source and
			STR		r3, [r1], #4						; store it to the destination.
			SUBS		r2, r2, #1						; decrement the counter.
			BNE		wordcopy						; ... copy more.
stop			MOV		r0, #0x18						; angel_SWIreason_ReportException
			LDR		r1, =0x20026						; ADP_Stopped_ApplicationExit
			SWI 		0x123456						; Angel semihosting ARM 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

This module can be made more efficient by using LDM and STM for as much of the copying as possible. Eight is a sensible number of words to transfer at a time, given the number of registers that the ARM has. The number of eight-word multiples in the block to be copied can be found (if r2 = number of words to be copied) using:

	MOVS 		r3, r2, LSR #3				; number of eight word multiples

This value can be used to control the number of iterations through a loop that copies eight words per iteration. When there are less than eight words left, the number of words left can be found (assuming that r2 has not been corrupted) using:

	ANDS		r2, r2, #7

Example 5.11 lists the block copy module rewritten to use LDM and STM for copying.

Example 5.11. 

			AREA 		Block, CODE, READONLY						; name this block of code.
num			EQU		20						; set number of words to be copied.
			ENTRY								; mark the first instruction to call.
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.
			MOV		sp, #0x400						; Set up stack pointer (r13).
blockcopy			MOVS		r3,r2, LSR #3						; Number of eight word multiples.
			BEQ		copywords						; Less than eight words to move?
			STMFD		sp!, {r4-r11}						; Save some working registers.
octcopy			LDMIA		r0!, {r4-r11}						; Load 8 words from the source
			STMIA		r1!, {r4-r11}						; and put them at the destination.
			SUBS		r3, r3, #1						; Decrement the counter.
			BNE		octcopy						; ... copy more.
			LDMFD		sp!, {r4-r11}						; Don't need these now - restore
											; originals.
copywords			ANDS		r2, r2, #7						; Number of odd words to copy.
			BEQ		stop						; No words left to copy?
wordcopy			LDR		r3, [r0], #4						; load a word from the source and
			STR		r3, [r1], #4						; store it to the destination.
			SUBS		r2, r2, #1						; Decrement the counter.
			BNE		wordcopy						; ... copy more.
stop			MOV		r0, #0x18						; angel_SWIreason_ReportException
			LDR		r1, =0x20026						; ADP_Stopped_ApplicationExit
			SWI 		0x123456						; Angel semihosting ARM 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