简体   繁体   English

ARM 汇编:错误指令“mov32”

[英]ARM assembly: bad instruction “mov32”

I wanted to load a 32bit constant into a register and I found a pseudo-instruction "mov32" on which can do this ( mov32 pseudo-instruction ).我想将一个 32 位常量加载到一个寄存器中,我发现了一个伪指令“mov32”,可以在上面执行此操作( mov32 伪指令)。 Then I write an assembly file which includes:然后我写了一个汇编文件,其中包括:

MOV32 r0, #0xABCDEF12

And compiled it with linaro toolchain(version 13.04):并使用 linaro 工具链(版本 13.04)编译它:

arm-linux-gnueabihf-as -march=armv7-a -mcpu=cortex-a9 test.s -o test.o

But it failed with message:但失败并显示以下消息:

Error: bad instruction `mov32 r0, #0xABCDEF12'

I don't know if it's the matter of unified assembly language.不知道是不是统一汇编语言的问题。 In case, I wrote ".syntax unified" in source code and tested again, but also failed.以防万一,我在源代码中写了“.syntax统一”并再次测试,但也失败了。 Does GNU toolchain support ARM pseudo-instruction like "mov32", "ldr r0, =address" etc. ? GNU 工具链是否支持 ARM 伪指令,如“mov32”、“ldr r0、=address”等? If does, how can I solve this problem?如果是,我该如何解决这个问题? Thanks.谢谢。

As has been mentioned by a commenter, MOV32 is a pseudo-instruction supported by ARM's own development tools .正如评论者所说, MOV32ARM自己的开发工具支持伪指令 Since you're using the GNU toolchain you've got a couple of options:由于您使用的是 GNU 工具链,因此您有几个选择:

You can, as dwelch mentioned, use LDR R0,=0xABCDEF12 .正如 dwelch 所提到的,您可以使用LDR R0,=0xABCDEF12
This is also a pseudo-instruction, which will result in the immediate constant being placed in a literal pool (small chunks of data scattered throughout the code section), which then is loaded using a PC-relative LDR .这也是一个伪指令,它将导致立即常量被放置在一个文字池中(散布在整个代码部分的小块数据),然后使用与 PC 相关的LDR加载。
If the constant can be encoded as imm8 ROR n (which it can't in your case, but let's say you had 0x80000000) then the LDR = psedo-instruction will be translated into a single MOV and won't add anything to the literal pool.如果常量可以被编码为imm8 ROR n (在你的情况下它不能,但假设你有 0x80000000)那么LDR = psedo-instruction 将被转换为单个MOV并且不会向文字添加任何内容水池。


You could also use the instructions that MOV32 translates into:您还可以使用MOV32转换为的指令:

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

This requires an ARMv6T2 or later.这需要 ARMv6T2 或更高版本。

In the GNU assembler, one can synthesize mov32 the following way:在 GNU 汇编器中,可以通过以下方式合成mov32

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

That'll work for ARMv7.这适用于 ARMv7。 If you'd want the "generic" behaviour (substitute it with ldr reg,=val where movw / movt don't exist), add a sprinkling of #ifdef .如果您想要“通用”行为(用ldr reg,=val替换它,其中movw / movt不存在),请添加一些#ifdef

(Credit where credit is due: This comes from arch/arm/mach-tegra/sleep.h of the ARM Linux kernel sources, not an invention of mine) (信用到期的信用:这来自 ARM Linux 内核源代码的arch/arm/mach-tegra/sleep.h ,不是我的发明)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM