5.6.2. Loading addresses with LDR Rd, = label

The LDR Rd,= pseudo-instruction can load any 32-bit constant into a register. See Loading with LDR Rd, =const. It also accepts program-relative expressions such as labels, and labels with offsets.

The assembler converts an LDR r0,=label pseudo-instruction by:

Unlike the ADR and ADRL pseudo-instructions, you can use LDR with labels that are outside the current area. If the label is outside the current area, the assembler places a relocation directive in the object code when the source file is assembled. The relocation directive instructs the linker to resolve the address at link time. The address remains valid wherever the linker places the area containing the LDR and the literal pool.

Example 5.8 shows how this works. It is supplied as ldrlabel.s in the examples\asm subdirectory of the toolkit. Refer to Code examples for instructions on how to assemble, link, and execute the example.

The instructions listed in the comments are the ARM instructions that are generated by the assembler.

Example 5.8. 

		ENTRY								; Mark first instruction to execute.
		BL		func1						; Branch to first subroutine.
		BL		func2						; Branch to second subroutine.
stop		MOV		r0, #0x18						; angel_SWIreason_ReportException
		LDR		r1, =0x20026						; ADP_Stopped_ApplicationExit
		SWI 		0x123456						; Angel semihosting ARM SWI
		LDR 		r0, =start						; => LDR R0,[PC, #offset to
										; Litpool 1]
		LDR 		r1, =Darea + 12 						; => LDR R1,[PC, #offset to
										; Litpool 1]
		LDR 		r2, =Darea + 6000						; => LDR R2, [PC, #offset to
										; Litpool 1]
		MOV		pc,lr						; Return
		LTORG								; Literal Pool 1
		LDR		r3, =Darea + 6000 						; => LDR r3, [PC, #offset to
										; Litpool 1]
										; (sharing with previous literal).
		; LDR		r4, =Darea + 6004						; If uncommented produces an
										; error as Litpool 2 is out of range.
		MOV		pc, lr						; Return
Darea		% 		8000						; Starting at the current location, 
										; clears a 8000 byte area of memory
										; to zero.
		END 								; Literal Pool 2 is out of range of
										; the LDR instructions above.

An LDR Rd, =label example: string copying

Example 5.9 shows an ARM code routine that overwrites one string with another string. It uses the LDR pseudo-instruction to load the addresses of the two strings from a data area. Note the following instructions and directives:


The DCB (Define Constant Byte) directive defines one or more bytes of store. In addition to integer values, DCB accepts quoted strings. Each character of the string is placed in a consecutive byte. Refer to Chapter 5 Assembler in the ARM Software Development Toolkit Reference Guide for more information.


The LDR and STR instructions use post-indexed addressing to update their address registers. For example, the instruction:

LDRB		r2,[r1],#1

loads r2 with the contents of the address pointed to by r1 and then increments r1 by 1.

Example 5.9.  String copy

		ENTRY								; Mark first instruction to execute.
start		LDR		r1, =srcstr						; Pointer to first string
		LDR		r0, =dststr						; Pointer to second string
		BL		strcopy						; Call subroutine to do copy.
stop		MOV		r0, #0x18						; angel_SWIreason_ReportException
		LDR		r1, =0x20026						; ADP_Stopped_ApplicationExit
		SWI 		0x123456						; Angel semihosting ARM SWI
		LDRB		r2, [r1],#1						; Load byte and update address.
		STRB		r2, [r0],#1						; Store byte and update address.
		CMP		r2, #0						; Check for zero terminator.
		BNE		strcopy						; Keep going if not.
		MOV		pc,lr						; Return
srcstr		DCB 		"First string - source",0
dststr		DCB 		"Second string - destination",0

Converting to Thumb

There is no post-indexed addressing mode for Thumb LDR and STR instructions. Because of this, you must use an ADD instruction to increment the address register after the LDR and STR instructions. For example:

		LDRB		r2, [r1]				; load register 2
		ADD		r1, #1				; increment the address in
								; register 1.
Copyright © 1997, 1998 ARM Limited. All rights reserved.ARM DUI 0040D