Assembler User GuideConventions and feedback Overview of the Assembler Overview of the ARM Architecture Structure of Assembly Language Modules Writing ARM Assembly Language Unified Assembler Language Subroutines calls Load immediates into registers Load immediate values using MOV and MVN Load 32-bit values to a register using MOV32 Load immediate 32-bit values to a register using L 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 instructions available in Stack implementation using LDM and STM Stack operations for nested subroutines Block copy with LDM and STM Memory accesses Read-Modify-Write procedure Optional hash 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 Assembly language changes after RVCTv2.1 Condition Codes Using the Assembler Symbols, Literals, Expressions, and Operators VFP Programming
Assembler User Guide
The assembler uses literal pools to hold certain constant
values that are to be loaded into registers. The assembler places
a literal pool at the end of each section. The end of a section
is defined either by the
In large sections the default literal pool can be out of range
of one or more
If the next literal pool is out of range, the assembler generates
an error message. In this case you must use the
You must place literal pools where the processor does not attempt to execute them as instructions. Place them after unconditional branch instructions, or after the return instruction at the end of a subroutine. Example 9 shows how this works.
The instructions listed as comments are the ARM instructions generated by the assembler.
Example 9. Placing literal pools
AREA Loadcon, 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, =42 ; => MOV R0, #42 LDR r1, =0x55555555 ; => LDR R1, [PC, #offset to ; Literal Pool 1] LDR r2, =0xFFFFFFFF ; => MVN R2, #0 BX lr LTORG ; Literal Pool 1 contains ; literal Ox55555555 func2 LDR r3, =0x55555555 ; => LDR R3, [PC, #offset to ; Literal Pool 1] ; LDR r4, =0x66666666 ; If this is uncommented it ; fails, because Literal Pool 2 ; is out of reach BX lr LargeTable SPACE 4200 ; Starting at the current location, ; clears a 4200 byte area of memory ; to zero END ; Literal Pool 2 is empty