ARM 程序集:错误指令“mov32”

wm8*_*120 2 assembly arm gnu-toolchain

我想将一个 32 位常量加载到一个寄存器中,我发现了一个伪指令“mov32”,可以在上面执行此操作(mov32 伪指令)。然后我写了一个汇编文件,其中包括:

MOV32 r0, #0xABCDEF12
Run Code Online (Sandbox Code Playgroud)

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

arm-linux-gnueabihf-as -march=armv7-a -mcpu=cortex-a9 test.s -o test.o
Run Code Online (Sandbox Code Playgroud)

但失败并显示以下消息:

Error: bad instruction `mov32 r0, #0xABCDEF12'
Run Code Online (Sandbox Code Playgroud)

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

Mic*_*ael 7

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

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


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

MOVW R0,#0xEF12  
MOVT R0,#0xABCD
Run Code Online (Sandbox Code Playgroud)

这需要 ARMv6T2 或更高版本。


Fra*_*kH. 5

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

.macro mov32, reg, val
    movw \reg, #:lower16:\val
    movt \reg, #:upper16:\val
.endm
Run Code Online (Sandbox Code Playgroud)

这适用于 ARMv7。如果您想要“通用”行为(用/不存在的ldr reg,=val地方替换它),请添加一点.movwmovt#ifdef

(功劳应归功于:这来自arch/arm/mach-tegra/sleep.hARM Linux 内核源代码,而不是我的发明)