2013-05-20 94 views
0

我想加载一个32位常量到一个寄存器中,我发现一个伪指令“mov32”可以在其上执行此操作(mov32 pseudo-instruction)。然后,我编写一个汇编文件,其中包括:ARM程序集:错误的指令“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 unified”并再次测试,但也失败了。 GNU工具链是否支持ARM伪指令,如“mov32”,“ldr r0,= address”等?如果确实如此,我该如何解决这个问题?谢谢。

+1

LDR RX = 0x12345678的会为你工作与GNU工具。 –

+0

您正在使用gnu汇编程序和arm汇编伪指令。 – auselen

回答

2

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

您可以按照提及的方式使用LDR R0,=0xABCDEF12
这也是一个伪指令,这将导致立即被置于文字池(分散在整个代码部分的小数据块)中,然后使用与PC相关的LDR进行加载。
如果常量可以编码为imm8 ROR n(它不能用于你的情况,但假设你有0x80000000),那么psedo指令将被翻译成一个单一的MOV,并且不会向文字池添加任何东西。


您也可以使用指令MOV32翻译成:

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

这需要ARMv6T2或更高版本。

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

+0

Protip:链接到git散列而不是分支。 – MBober