4.13.3. LDR 伪指令

使用以下项之一加载寄存器:

Note

本节仅介绍 LDR 指令。 有关 LDR 指令 的详细信息,请参阅 内存访问指令

语法

LDR{cond}{.W} Rt, =expr
LDR{cond}{.W} Rt, =label_expr

其中:

cond

是一个可选的条件代码(请参阅条件执行)。

.W

是可选的指令宽度说明符。

Rt

是要加载的寄存器。

expr

取值为一个数值常数(请参阅数字常数):

  • 如果 expr 的值位于范围内,则汇编器将会生成一个 MOVMVN 指令。

  • 如果 expr 的值不在 MOVMVN 指令的范围内,则汇编器会将常数放入文字池中,并会生成一个相对于程序的 LDR 指令,该指令可从文字池中读取此常数。

有关加载常数的信息,请参阅用 LDR Rd, =const 加载

label_expr

是地址的程序相对表达式或外部表达式,形式为加上或减去一个数值常数的标签(有关详细信息,请参阅相对寄存器和程序相对的表达式)。 汇编器将 label_expr 的值放入文字池中,并会生成一个相对于程序的 LDR 指令,该指令可从文字池中加载该值。

如果 label_expr 是一个外部表达式,或未包含在当前代码段内,则汇编器会在对象文件中放入一个链接器重新定位指令。 链接器将在链接时生成该地址。

如果 label_expr 是一个局部标签(请参阅局部标签),则汇编器会在对象文件中放入一个链接器重新定位指令,并会为该局部标签生成一个符号。 该地址将在链接时生成。 如果局部标签引用了 Thumb 代码,则还会设置该地址的 Thumb 位(位 0)。

Note

在 RVCT v2.2 中,没有对地址的 Thumb 位进行设置。 如果此设置会影响您的代码,则请使用命令行选项 --untyped_local_labels 强制汇编器在引用 Thumb 代码中的标签时不设置 Thumb 位。

用法

LDR 伪指令的主要功能有:

  • 当立即数由于超出了 MOVMVN 指令的范围,而不能被移入寄存器中时,生成文字常数。

  • 将相对于程序的地址或外部地址载入寄存器中。 无论链接器将包含 LDR 的 ELF 代码段置于何处,该地址始终有效。

    Note

    以这种方式加载的地址在链接时是固定的,因此代码不是 位置无关的。

pc 到文字池中的值的偏移量必须小于 ±4KB(ARM、32 位 Thumb-2),或在 0 到 +1KB 范围内(16 位 Thumb-2、Thumb2 之前的 Thumb)。 您必须确保有一个满足范围要求的文字池。 有关详细信息,请参阅LTORG

如果引用的标签在 Thumb 代码中,则 LDR 伪指令会设置 label_expr 的 Thumb 位(位 0)。

有关如何使用 LDR 的详细说明,以及有关 MOVMVN 的详细信息,请参阅将常数加载到寄存器

Thumb 代码中的 LDR

在 ARMv6T2 及更高版本处理器上的 Thumb 代码中,可以使用 .W 宽度说明符强制 LDR 生成 32 位指令。LDR.W 始终生成 32 位指令,即使利用 16 位 MOV 就可完成常数的加载,或在 16 位 pc 相关加载范围内有文字池。

如果在第一轮汇编时,汇编器尚不知道常数的值,则不带 .WLDR 会在 Thumb 代码中生成 16 位指令,即使这会导致对可以在 32 位 MOVMVN 指令中生成的常数进行 16 位 pc 相关加载。 但是,如果在第一次汇编时汇编器就已经知道了该常数,并且该常数可以通过 32 位 MOVMVN 指令生成,则将会使用 MOVMVN 指令。

LDR 伪指令从不生成 16 位标记设置 MOV 指令。 可使用 --diag_warning 1727 汇编器命令行选项来检查是否使用了 16 位指令。

有关如何在不利用文字池加载的情况下来生成常数或地址的信息,请参阅MOV32 伪指令

示例

        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
Copyright © 2002-2008 ARM Limited. All rights reserved.ARM DUI 0204IC
Non-Confidential