The ADR
instruction enables you to generate 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 current 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:
- ARM
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 Thumb
±4095 bytes to a byte, halfword, or word-aligned address.
- 16-bit Thumb
0 to 1020 bytes.
must be word-aligned. You can use thelabel
ALIGN
directive to ensure this.
Example 10 shows ARM
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 ARM code num EQU 2 ; Number of entries in jump table ENTRY ; Mark first instruction to execute start ; First instruction to call MOV r0, #0 ; Set up the three parameters MOV r1, #3 MOV r2, #2 BL arithfunc ; Call the function stop 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 simply return ADR r3, JumpTable ; Load address of jump table LDR pc, [r3,r0,LSL#2] ; Jump to the appropriate routine JumpTable DCD DoAdd DCD DoSub DoAdd ADD r0, r1, r2 ; Operation 0 BX lr ; Return DoSub SUB r0, r1, r2 ; Operation 1 BX lr ; Return END ; Mark the end of this file
In Example 10,
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. It is used to give a value to a symbol. In Example 10 it assigns the value 2 to
. Whennum
is used elsewhere in the code, the value 2 is substituted. Usingnum
EQU
in this way is similar to using#define
to define a constant in C.DCD
Declares one or more words of store. In Example 10 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 offsetadds the result to the address of the jump table
loads the contents of the combined address into the PC.
- Concepts
- Reference
Assembler Reference: