| |||
Home > Writing ARM Assembly Language > Load addresses to a register using LDR Rd, =label |
The LDR Rd,=
pseudo-instruction can load any
32-bit numeric value into a register. It also accepts PC-relative
expressions such as labels, and labels with offsets.
The assembler converts an LDR R0, =
pseudo-instruction
by:label
placing the address of
in
a literal pool (a portion of memory embedded in the code to hold
constant values)label
generating a PC-relative LDR
instruction
that reads the address from the literal pool, for example:
LDR rn
[pc, #offset to literal pool] ; load registern
with one word ; from the address [pc + offset]
You must ensure that there is a literal pool within range (see Literal pools for more information).
Unlike the ADR
and ADRL
pseudo-instructions,
you can use LDR
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.
Example 11 shows how this works.
The instructions listed in the comments are the ARM instructions generated by the assembler.
Example 11. Loading using LDR Rd, =label
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 ; as 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 out of range of ; the LDR instructions above
Example 12 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 section. The following are particularly
significant:
DCB
The DCB
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.
LDR, STR
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 12. String copy
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
Assembler Reference: