出于某种原因,当我尝试编译这段代码时,编译器会说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, #300
和add r7, #70
临时修复了它,达到了预期的效果。仍不确定导致错误的原因。
答案 0 :(得分:41)
ARM指令只能使用mov加载有限范围的立即值。问题是该值必须在mov指令本身中编码。由于所有ARM指令都是32位宽,因此ARMv5的原始指令设置总共只有8 + 4位来编码。第一个8位能够在0-255的范围内加载任何8位值int,而右边的4位在0到30之间以2的步长旋转。
因此您可以加载以下值:
#0
#122
#121 ror #24 = 30976
#230 ror #12 = 241172480
但是,#370不能用这个方案加载,它需要像#185 ror #31
这样的东西是不可能的。
有两种方法可以加载您的直接值。
ldr r7,=#370
然后汇编器将创建一个常量池,并通过pc相对寻址从那里加载值。通常你应该更喜欢用最多2个指令构造常量,如果不可能(或者值必须是可重定位的)使用ldr。
从ARMv7开始,您还可以使用movw
在寄存器的下半部分加载任何16位值,同时将上半部分归零,movt
将另一个16位值加载到上半部分而不用触摸下半部分。