You copied the Doc URL to your clipboard.

Load addressesto a register using ADR

The ADR instruction loads an address within a certain range, without performing a data load.

ADR accepts a PC-relative expression, that is, a label with an optional offset where the address of the label is relative to the PC.

Note

The label used with ADR must be within the same code section. The assembler faults references to labels that are out of range in the same section.

The available range of addresses for the ADR instruction depends on the instruction set and encoding:

A32

Any value that can be produced by rotating an 8-bit value right by any even number of bits within a 32-bit word. The range is relative to the PC.

32-bit T32 encoding

±4095 bytes to a byte, halfword, or word-aligned address.

16-bit T32 encoding

0 to 1020 bytes. label must be word-aligned. You can use the ALIGN directive to ensure this.

Example of a jump table implementation with ADR

This example shows A32 code that implements a jump table. Here, the ADR instruction loads the address of the jump table.

        AREA   Jump, CODE, READONLY ; Name this block of code        ARM                         ; Following code is A32 codenum     EQU    2                    ; Number of entries in jump table        ENTRY                       ; Mark first instruction to executestart                               ; First instruction to call        MOV    r0, #0               ; Set up the three arguments        MOV    r1, #3        MOV    r2, #2        BL     arithfunc            ; Call the functionstop        MOV    r0, #0x18            ; angel_SWIreason_ReportException        LDR    r1, =0x20026         ; ADP_Stopped_ApplicationExit        SVC    #0x123456            ; ARM semihosting (formerly SWI)arithfunc                           ; Label the function        CMP    r0, #num             ; Treat function code as unsigned                                    ; integer        BXHS   lr                   ; If code is >= num then return        ADR    r3, JumpTable        ; Load address of jump table        LDR    pc, [r3,r0,LSL#2]    ; Jump to the appropriate routineJumpTable        DCD    DoAdd        DCD    DoSubDoAdd        ADD    r0, r1, r2           ; Operation 0        BX     lr                   ; ReturnDoSub        SUB    r0, r1, r2           ; Operation 1        BX     lr                   ; Return        END                         ; Mark the end of this file

In this example, the function arithfunc takes three arguments and returns a result in R0. The first argument determines the operation to be carried out on the second and third arguments:

argument1=0

Result = argument2 + argument3.

argument1=1

Result = argument2 – argument3.

The jump table is implemented with the following instructions and assembler directives:

EQU

Is an assembler directive. You use it to give a value to a symbol. In this example, it assigns the value 2 to num. When num is used elsewhere in the code, the value 2 is substituted. Using EQU in this way is similar to using #define to define a constant in C.

DCD

Declares one or more words of store. In this example, each DCD stores the address of a routine that handles a particular clause of the jump table.

LDR

The LDR PC,[R3,R0,LSL#2] instruction loads the address of the required clause of the jump table into the PC. It:

  • Multiplies the clause number in R0 by 4 to give a word offset.
  • Adds the result to the address of the jump table.
  • Loads the contents of the combined address into the PC.

Related reference