| |||
| Home > Writing ARM and Thumb Assembly Language > Loading addresses into registers > 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,= 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 program-relative LDR instruction
that reads the address from the literal pool, for example:
LDR rn [pc, #offset to literal pool]
; load register n with one word
; from the address [pc + offset]
You must ensure that there is a literal pool within range. Refer to Placing literal pools for more information.
Unlike the ADR and ADRL pseudo-instructions,
you can use LDR with labels that are outside the current
section. If the label is 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 2.9 shows how
this works. It is supplied as ldrlabel.s in
the examples\asm subdirectory of the ADS.
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 2.9.
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
SWI 0x123456 ; ARM semihosting 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]
MOV pc,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
MOV pc, 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 2.10 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:
DCBThe 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. Refer to DCB for
more information.
LDR/STRThe 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 2.10. 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
SWI 0x123456 ; ARM semihosting 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
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.