4.11 Load addresses to a register using LDR Rd, =label

The LDR Rd,=label pseudo-instruction places an address in a literal pool and then loads the address into a register.

LDR Rd,=label 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 Rd,=label pseudo-instruction by:

  • Placing the address of label in a literal pool (a portion of memory embedded in the code to hold constant values).
  • Generating a PC-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 the literal pool is within range of the LDR pseudo-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 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.

The example also shows how, unlike the ADR and 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
Non-ConfidentialPDF file icon PDF versionARM DUI0473M
Copyright © 2010-2016 ARM Limited or its affiliates. All rights reserved.