Load addresses to a register using LDR Rd, =label
LDR Rd,= pseudo-instruction places an address in a literal pool and then loads the address into a register.
LDR Rd,= can load any 32-bit numeric value into a
register. It also accepts PC-relative expressions such as labels, and labels with
The assembler converts an
LDR Rd,= pseudo-instruction by:
- Placing the address of
in a literal pool (a portion of memory embedded in the code to hold constant values).
- Generating a PC-relative
LDRinstruction that reads the address from the literal pool, for example:
n[pc, #offset_to_literal_pool] ; load register
nwith one word ; from the address [pc + offset]
You must ensure that the literal pool is within range of the
LDRpseudo-instruction that needs to access it.
Example of loading using LDR Rd, =label
The following example shows a section with two literal pools. The final
LDR pseudo-instruction needs to access the second literal pool, but it is
out of range. Uncommenting this line causes the assembler to generate an error.
The instructions listed in the comments are the ARM instructions generated by the assembler.
AREA LDRlabel, CODE, READONLY ENTRY ; Mark first instruction to execute start 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 SVC #0x123456 ; ARM semihosting (formerly SWI) func1 LDR r0, =start ; => LDR r0,[PC, #offset into Literal Pool 1] LDR r1, =Darea + 12 ; => LDR r1,[PC, #offset into Literal Pool 1] LDR r2, =Darea + 6000 ; => LDR r2,[PC, #offset into Literal Pool 1] BX lr ; Return LTORG ; Literal Pool 1 func2 LDR r3, =Darea + 6000 ; => LDR r3,[PC, #offset into Literal Pool 1] ; (sharing with previous literal) ; LDR r4, =Darea + 6004 ; If uncommented, produces an error because ; Literal Pool 2 is out of range. BX lr ; Return Darea SPACE 8000 ; Starting at the current location, clears ; a 8000 byte area of memory to zero. END ; Literal Pool 2 is automatically inserted ; after the END directive. ; It is out of range of all the LDR ; pseudo-instructions in this example.
Example of string copy
The following example shows an ARM code routine
that overwrites one string with another. It uses the
pseudo-instruction to load the addresses of the two strings from a data section. The
following are particularly significant:
DCBdirective defines one or more bytes of store. In addition to integer values,
DCBaccepts quoted strings. Each character of the string is placed in a consecutive byte.
STRinstructions use post-indexed addressing to update their address registers. For example, the instruction:
R2with the contents of the address pointed to by
R1and then increments
The example also shows how, unlike the
ADRL pseudo-instructions, you can use the
LDR pseudo-instruction with labels that are outside the current
section. 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 section containing the
LDR and the literal pool.
AREA StrCopy, CODE, READONLY 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 SVC #0x123456 ; ARM semihosting (formerly SWI) strcopy 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 AREA Strings, DATA, READWRITE srcstr DCB "First string - source",0 dststr DCB "Second string - destination",0 END