| |||
| Home > ARM and Thumb Instructions > Pseudo-instructions > LDR pseudo-instruction | |||
Load a register with either:
a 32-bit immediate value
an address.
This section describes the LDR pseudo-instruction
only, and not the LDR instruction.
LDR{cond}{.W}Rt, =expr
LDR{cond}{.W}Rt, =label_expr
where:
condis an optional condition code.
.Wis an optional instruction width specifier.
Rtis the register to be loaded.
exprevaluates to a numeric value.
label_expris a PC-relative or external expression of an address in the form of a label plus or minus a numeric value.
When using the LDR pseudo-instruction:
If the value of expr can
be loaded with a valid MOV or MVN instruction,
the assembler uses that instruction.
If a valid MOV or MVN instruction
cannot be used, or if the label_expr syntax is used,
the assembler places the constant in a literal pool and generates
a PC-relative LDR instruction that reads the constant
from the literal pool.
An address loaded in this way is fixed at link time, so the code is not position-independent.
The address holding the constant remains valid regardless
of where the linker places the ELF section containing the LDR instruction.
The assembler places the value of in
a literal pool and generates a PC-relative label_exprLDR instruction
that loads the value from the literal pool.
If is
an external expression, or is not contained in the current section,
the assembler places a linker relocation directive in the object
file. The linker generates the address at link time.label_expr
If is
a local label, the assembler places a linker relocation directive
in the object file and generates a symbol for that local label.
The address is generated at link time. If the local label references
Thumb code, the Thumb bit (bit 0) of the address is set.label_expr
The offset from the PC to the value in the literal pool must be less than ±4KB (ARM, 32-bit Thumb) or in the range 0 to +1KB (16-bit Thumb). You are responsible for ensuring that there is a literal pool within range.
If the label referenced is in Thumb code, the LDR pseudo-instruction
sets the Thumb bit (bit 0) of .label_expr
In RealView® Compilation
Tools (RVCT) v2.2, the Thumb bit of the address was not
set. If you have code that relies on this behavior, use the command
line option --untyped_local_labels to force the
assembler not to set the Thumb bit when referencing labels in Thumb
code.
You can use the .W width specifier to force LDR to
generate a 32-bit instruction in Thumb code on ARMv6T2 and above
processors. LDR.W always generates a 32-bit instruction,
even if the immediate value could be loaded in a 16-bit MOV,
or there is a literal pool within reach of a 16-bit PC-relative
load.
If the value to be loaded is not known in the first pass of
the assembler, LDR without .W generates a
16-bit instruction in Thumb code, even if that results in a 16-bit
PC-relative load for a value that could be generated in a 32-bit MOV or MVN instruction.
However, if the value is known in the first pass, and it can be
generated using a 32-bit MOV or MVN instruction,
the MOV or MVN instruction is used.
The LDR pseudo-instruction never generates a
16-bit flag-setting MOV instruction. Use the --diag_warning
1727 assembler command line option to check when a 16-bit
instruction could have been used.
You can use the MOV32 pseudo-instruction for
generating immediate values or addresses without loading from a
literal pool.
LDR r3,=0xff0 ; loads 0xff0 into R3
; => MOV.W r3,#0xff0
LDR r1,=0xfff ; loads 0xfff into R1
; => LDR r1,[pc,offset_to_litpool]
; ...
; litpool DCD 0xfff
LDR r2,=place ; loads the address of
; place into R2
; => LDR r2,[pc,offset_to_litpool]
; ...
; litpool DCD place