【问题标题】:Error while compiling MOV instruction in ARM assembly在 ARM 汇编中编译 MOV 指令时出错
【发布时间】:2021-09-16 06:59:42
【问题描述】:

我使用的是 RVDS6_13 编译器,我的处理器是 Cortex X1 (HERA)。对于需要进行一些汇编语言编程的测试,我在编译时遇到以下错误:

错误:A1616E:当前指令集不支持指令、偏移量、立即数或寄存器组合 9 00000000 MOV x28,0xD02E7F30

基本上我需要加载 0xB41138A4 到地址位置 0xD02E7F30,下面是我的代码:

 MOV  x28,0xD02E7F30  
 STR  x28,0xB41138A4   

【问题讨论】:

  • 您不需要mov w28, 0x7F30movk w28, 0xD02E, lsl 16 之类的东西吗?另外,STR 在我看来不像 ARM 程序集。通常,您首先将地址加载到寄存器中,然后使用[reg] 作为第二个操作数(其中reg 是您放置地址的寄存器)。
  • 谢谢 Michael,其实我在想如果 x28、x29 是 32 位寄存器,那为什么我不能直接用 32 位字加载地址和数据,然后通过 STR 指令加载地址数据。但似乎虽然这些是 32 位寄存器,但我必须按照您的建议将它分成两个 16 位操作和左移才能有效地获得 32 位操作。

标签: assembly arm64 mov armv8 immediate-operand


【解决方案1】:

使用特殊的“文字池”LDR 指令加载值,并使用 ADRP 指令加载部分地址(除了低 12 位之外的所有内容)。然后将剩余的地址位作为位移存储:

LDR w28, =0xD02E7F30
ADRP x29, 0xB4113000
STR w28, [x29, 0x8A4]

(我已将您的存储更改为 32 位存储,因为我假设您错误地使用了 64 位存储)

除了ldr w28, =... 指令,您还可以使用MOVZ/MOVK 对来摆脱文字池负载:

MOVZ w28, 0x7F30, LSL #0
MOVK w28, 0xD02E, LSL #16
ADRP x29, 0xB4113000
STR w28, [x29, 0x8A4]

如果您的二进制文件应该与位置无关,您还必须使用LDR w29, =...MOVZ/MOVK 加载地址,因为ADRP 加载PC 相对地址:

MOVZ w28, 0x7F30, LSL #0
MOVK w28, 0xD02E, LSL #16
MOVZ x29, 0x38A4, LSL #0
MOVK x29, 0XB411, LSL #16
STR w28, [x29]

【讨论】:

  • 非常感谢。我使用了最后一个解决方案,至少得到了一个无错误的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 2015-02-25
相关资源
最近更新 更多