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”等?如果是,我该如何解决这个问题?谢谢。
正如评论者所说,MOV32是ARM自己的开发工具支持的伪指令。由于您使用的是 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 或更高版本。
在 GNU 汇编器中,可以mov32通过以下方式合成:
.macro mov32, reg, val
movw \reg, #:lower16:\val
movt \reg, #:upper16:\val
.endmRun Code Online (Sandbox Code Playgroud)
这适用于 ARMv7。如果您想要“通用”行为(用/不存在的ldr reg,=val地方替换它),请添加一点.movwmovt#ifdef
(功劳应归功于:这来自arch/arm/mach-tegra/sleep.hARM Linux 内核源代码,而不是我的发明)