当我有以下代码时:
int value2 = 0x11223344;
VS2022编译器(arm64)生成:
StarFunction PROC
...
ldr w8,|value_label|
...
...
...
ret
|value_label|
DCD 0x11223344
ENDP
如您所见,值 0x11223344 在函数末尾生成为“数据”。
有什么办法可以控制它,所以它会生成:
mov w8, 0x1122
movk w8, 0x3344, lsl 16
我不能使用编译器优化,因为我需要控制生成的 代码来修补特定的代码序列。通过编译器优化,我失去了控制权。
我尝试了不同的编译器优化开关,但其中一些没有效果,并且 其他更积极的优化甚至删除“0x11223344”的声明并直接 之后在代码中使用它。
总结一下,我能否以某种方式“强制”编译器避免“数据”与 arm64 中的立即值代码混合?
我发现用“volatile”声明局部变量,例如:
void MyFunction()
{
volatile int i = 0x1123344;
// some code here
}
并且还使用
/Ox
进行编译,使编译器在声明它的预期位置生成所需的 mov Wn, imm16_low; movk Wn, imm16_high, lsl 16
。
这里有一个完整的例子(用
/Ox
编译)
int TestFunction()
{
volatile int a = 0x11223344;
volatile int b = 0x77887788;
return 0;
}
生成:
|int TestFunction(void)| PROC
|$LN6|
sub sp,sp,#0x10
mov w8,#0x3344
movk w8,#0x1122,lsl #0x10
str w8,[sp]
mov w8,#0x7788
movk w8,#0x7788,lsl #0x10
str w8,[sp]
mov w0,#0
add sp,sp,#0x10
ret
ENDP ; |int TestFunction(void)|, TestFunction