Keil Logo

Technical Support

On-Line Manuals

Compiler Reference Guide

Preface Arm Compiler Tools Overview armclang Reference armlink Reference fromelf Reference armar Reference armasm Legacy Assembler Reference armasm Command-line Options --16 --32 --apcs=qualifier…qualifier --arm --arm_only --bi --bigend --brief_diagnostics, --no_brief_diagnostics --checkreglist --cpreproc --cpreproc_opts=option[,option,…] --cpu=list (armasm) --cpu=name (armasm) --debug --depend=dependfile --depend_format=string --diag_error=tag[,tag,…] (armasm) --diag_remark=tag[,tag,…] (armasm) --diag_style={arm|ide|gnu} (armasm) --diag_suppress=tag[,tag,…] (armasm) --diag_warning=tag[,tag,…] (armasm) --dllexport_all --dwarf2 --dwarf3 --errors=errorfile --exceptions, --no_exceptions --exceptions_unwind, --no_exceptions_unwind --execstack, --no_execstack --execute_only --fpmode=model --fpu=list (armasm) --fpu=name (armasm) -g (armasm) --help (armasm) -idir[,dir, …] --keep (armasm) --length=n --li --library_type=lib --list=file --list= --littleend -m (armasm) --maxcache=n --md --no_code_gen --no_esc --no_hide_all --no_regs --no_terse --no_warn -o filename (armasm) --pd --predefine "directive" --reduce_paths, --no_reduce_paths --regnames --report-if-not-wysiwyg --show_cmdline (armasm) --thumb --unaligned_access, --no_unaligned_access --unsafe --untyped_local_labels --version_number (armasm) --via=filename (armasm) --vsn (armasm) --width=n --xref Structure of armasm Assembly Language Modules Syntax of source lines in armasm syntax assembly l Literals ELF sections and the AREA directive An example armasm syntax assembly language module Writing A32/T32 Instructions in armasm Syntax Asse About the Unified Assembler Language Syntax differences between UAL and A64 assembly la Register usage in subroutine calls Load immediate values Load immediate values using MOV and MVN Load immediate values using MOV32 Load immediate values using LDR Rd, =const Literal pools Load addresses into registers Load addresses to a register using ADR Load addresses to a register using ADRL Load addresses to a register using LDR Rd, =label Other ways to load and store registers Load and store multiple register instructions Load and store multiple register instructions in A Stack implementation using LDM and STM Stack operations for nested subroutines Block copy with LDM and STM Memory accesses The Read-Modify-Write operation Optional hash with immediate constants Use of macros Test-and-branch macro example Unsigned integer division macro example Instruction and directive relocations Symbol versions Frame directives Exception tables and Unwind tables Using armasm armasm command-line syntax Specify command-line options with an environment v Using stdin to input source code to the assembler Built-in variables and constants Identifying versions of armasm in source code Diagnostic messages Interlocks diagnostics Automatic IT block generation in T32 code T32 branch target alignment T32 code size diagnostics A32 and T32 instruction portability diagnostics T32 instruction width diagnostics Two pass assembler diagnostics Using the C preprocessor Address alignment in A32/T32 code Address alignment in A64 code Instruction width selection in T32 code Symbols, Literals, Expressions, and Operators in a Symbol naming rules Variables Numeric constants Assembly time substitution of variables Register-relative and PC-relative expressions Labels Labels for PC-relative addresses Labels for register-relative addresses Labels for absolute addresses Numeric local labels Syntax of numeric local labels String expressions String literals Numeric expressions Syntax of numeric literals Syntax of floating-point literals Logical expressions Logical literals Unary operators Binary operators Multiplicative operators String manipulation operators Shift operators Addition, subtraction, and logical operators Relational operators Boolean operators Operator precedence Difference between operator precedence in assembly armasm Directives Reference Alphabetical list of directives armasm assembly la About armasm assembly language control directives About frame directives Directives that can be omitted in pass 2 of the as ALIAS ALIGN AREA ARM or CODE32 directive ASSERT ATTR CN CODE16 directive COMMON CP DATA DCB DCD and DCDU DCDO DCFD and DCFDU DCFS and DCFSU DCI DCQ and DCQU DCW and DCWU END ENDFUNC or ENDP ENTRY EQU EXPORT or GLOBAL EXPORTAS FIELD FRAME ADDRESS FRAME POP FRAME PUSH FRAME REGISTER FRAME RESTORE FRAME RETURN ADDRESS FRAME SAVE FRAME STATE REMEMBER FRAME STATE RESTORE FRAME UNWIND ON FRAME UNWIND OFF FUNCTION or PROC GBLA, GBLL, and GBLS GET or INCLUDE IF, ELSE, ENDIF, and ELIF IMPORT and EXTERN INCBIN INFO KEEP LCLA, LCLL, and LCLS LTORG MACRO and MEND MAP MEXIT NOFP OPT QN, DN, and SN RELOC REQUIRE REQUIRE8 and PRESERVE8 RLIST RN ROUT SETA, SETL, and SETS SPACE or FILL THUMB directive TTL and SUBT WHILE and WEND WN and XN armasm-Specific A32 and T32 Instruction Set Featur armasm support for the CSDB instruction A32 and T32 pseudo-instruction summary ADRL pseudo-instruction CPY pseudo-instruction LDR pseudo-instruction MOV32 pseudo-instruction NEG pseudo-instruction UND pseudo-instruction Appendixes

Load addresses to a register using ADR

F3.10 Load addresses to 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.


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:


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 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 arguments
        MOV    r1, #3
        MOV    r2, #2
        BL     arithfunc            ; Call the function
        MOV    r0, #0x18            ; angel_SWIreason_ReportException
        LDR    r1, =0x20026         ; ADP_Stopped_ApplicationExit
        SVC    #0x123456            ; AArch32 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 routine
        DCD    DoAdd
        DCD    DoSub
        ADD    r0, r1, r2           ; Operation 0
        BX     lr                   ; Return
        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:


Result = argument2 + argument3.


Result = argument2 – argument3.

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


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.


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.


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.
Non-ConfidentialPDF file icon PDF version101754_0614_00_en
Copyright © 2019, 2020 Arm Limited or its affiliates. All rights reserved. 
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.