26

出于某种原因,当我尝试编译这段代码时,编译器会说syscall.s:72:invalid constant (0x172) after fixup

.globl _mach_msg_trap$MACH
_mach_msg_trap$MACH:
    stmfd sp!, {r4,r7}
    mov r7, #370 /* this is line 72 */
    svc 0
    ldmfd sp!, {r4, r7}
    bx lr

我不知道它为什么这样做。当我将一个较小的常数放入r7时,它可以正常工作。但是随着数字的增加,它会吐出这个错误。我通过mov r7, #300and临时修复了它add r7, #70,达到了预期的效果。仍然不确定是什么导致了错误。

4

1 回答 1

49

直到 ARMv5 的 ARM 指令集只能使用有限范围的立即数。问题是该值必须在指令本身中进行编码。由于所有 ARM 指令都是 32 位宽的,因此 ARMv5 的原始指令集总共只有 8+4 位来编码立即数。前 8 位能够加载 0-255 范围内的任何 8 位值,而第 4 位可以在 0 到 30 之间以 2 的步长进行右循环。

因此,您可以加载如下值:

#0
#122
#121 ror #24 = 30976
#230 ror #12 = 241172480

但是,#370 不能用这个方案加载,它需要类似的东西,#185 ror #31这是不可能的。

有两种方法可以加载您的即时价值。

  1. 您如何通过在多个步骤中构建值来解决它。
  2. 通过使用 ldr 从内存中加载值:ldr r7,=#370然后,汇编器将创建一个常量池并通过 pc 相对寻址从那里加载值。

通常你应该更喜欢用最多 2 条指令来构造常量,如果那是不可能的(或者值必须是可重定位的)使用 ldr。

从 ARMv7 开始,您还可以使用movw将任何 16 位值加载到寄存器的下半部分,同时将上半部分归零,并将movt另一个 16 位值加载到上半部分而不接触下半部分。

于 2012-04-21T18:25:04.017 回答