2

我想将一个 32 位常量加载到一个寄存器中,我发现了一个伪指令“mov32”,它可以做到这一点(mov32 伪指令)。然后我编写了一个汇编文件,其中包括:

MOV32 r0, #0xABCDEF12

并使用 linaro 工具链(版本 13.04)编译它:

arm-linux-gnueabihf-as -march=armv7-a -mcpu=cortex-a9 test.s -o test.o

但它失败了消息:

Error: bad instruction `mov32 r0, #0xABCDEF12'

不知道是不是统一汇编语言的问题。以防万一,我在源代码中写了“.syntax unity”并再次测试,但也失败了。GNU 工具链是否支持“mov32”、“ldr r0、=address”等 ARM 伪指令?如果是,我该如何解决这个问题?谢谢。

4

2 回答 2

7

正如评论者所提到的,MOV32ARM 自己的开发工具支持的伪指令。由于您使用的是 GNU 工具链,因此您有几个选择:

正如 dwelch 所提到的,您可以使用LDR R0,=0xABCDEF12.
这也是一个伪指令,它将导致立即常量被放置在一个文字池中(小块数据分散在整个代码部分),然后使用 PC-relative 加载LDR
如果可以将常量编码为imm8 ROR n(在您的情况下不能编码,但假设您有 0x80000000),那么LDR =伪指令将被转换为单个指令MOV,并且不会向文字池添加任何内容。


您还可以使用MOV32转换为的说明:

MOVW R0,#0xEF12  
MOVT R0,#0xABCD

这需要 ARMv6T2 或更高版本。

于 2013-05-21T06:01:55.800 回答
5

在 GNU 汇编器中,可以mov32通过以下方式合成:

.macro mov32, reg, val
    movw \reg, #:lower16:\val
    movt \reg, #:upper16:\val
.endm

这适用于 ARMv7。如果您想要“通用”行为(将其替换为ldr reg,=valwhere movw/ movtdon't exist),请添加少量#ifdef.

(信用到期:这来自arch/arm/mach-tegra/sleep.hARM Linux 内核源,不是我的发明)

于 2013-05-21T08:56:31.117 回答