本文介绍了修复后常量无效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For some reason, when I try to compile this bit of code, the compiler says 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,#300add r7,#70临时修复,达到了预期的效果.仍然不确定是什么导致了错误.

I don't know why it's doing it. When I put a smaller constant into r7, it works fine. But with higher numbers, it spits out this error. I've temporary fixed it by doing mov r7, #300 and add r7, #70, which achieves the desired effect. Still not sure what caused the error though.

推荐答案

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

The ARM Instruction Set, up to ARMv5, is only able to use a limited range of immediate values. The problem is that the value has to be encoded in the instruction itself. As all ARM Instructions are 32-bit wide, the original instruction-set up to ARMv5 only had a total of 8+4 bits to encode immediates. With the first 8-bit being able to load any 8-bit value in the range of 0-255 and the 4 bit being a right rotate in steps of 2 between 0 and 30.

因此您可以加载如下值:

So you can load values like:

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

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

But, #370 is not loadable with this scheme, it would require something like #185 ror #31 which is not possible.

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

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

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

Usually you should prefer to construct constants with up to 2 instructions, if thats not possible (or the value has to be relocatable) use ldr.

从 ARMv7 开始,您还可以使用 movw 在寄存器的下半部分加载任何 16 位值,同时对上半部分和 movt 在不触及下半部分的情况下将另一个 16 位值加载到上半部分.

Starting with ARMv7 you can also use movw to load any 16 bit value in the lower half of a register while zeroing the top-half and movt to load another 16bit value to the upper half without touching the lower half.

这篇关于修复后常量无效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 21:14