我想将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”等?如果可以,我该如何解决这个问题?感谢。
答案 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
,而不是我的发明)