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

时间:2013-05-20 19:47:55

标签: assembly arm gnu-toolchain

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

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 unified”并再次测试,但也失败了。 GNU工具链是否支持ARM伪指令,如“mov32”,“ldr r0,= address”等?如果可以,我该如何解决这个问题?感谢。

2 个答案:

答案 0 :(得分:2)

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

你可以像经常提到的那样使用LDR R0,=0xABCDEF12
这也是一个伪指令,它会立即将常量放在文字池中(分散在整个代码部分的小块数据),然后使用PC相对LDR加载。
如果常量可以编码为imm8 ROR n(它不能在你的case,但是假设你有0x80000000)那么LDR = psedo-instruction将被翻译成单个MOV并且不会向文字池添加任何内容。


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

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

这需要ARMv6T2或更高版本。

答案 1 :(得分:2)

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

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

这对ARMv7起作用。如果您想要“通用”行为(将其替换为ldr reg,=val / movw不存在的movt),请添加#ifdef

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