assembly Visual Studio 2022,我可以控制如何为arm64编译生成立即值吗?

k5ifujac  于 2023-05-07  发布在  其他
关注(0)|答案(1)|浏览(189)

当我有以下代码时:

int value2 = 0x11223344;

VS2022编译器(arm64)生成:

StarFunction PROC 

...
ldr         w8,|value_label|
...
...
...

ret 

|value_label|
    DCD         0x11223344 

ENDP

如您所见,值0x11223344在函数末尾生成为“data”。
有没有什么方法可以控制它,这样它就可以生成:

mov  w8, 0x1122
movk w8, 0x3344, lsl 16

我不能使用编译器优化,因为我需要控制生成的代码来修补特定的代码序列。通过编译器优化,我失去了这种控制。
我已经尝试了不同的编译器优化开关,但其中一些没有效果,其他更积极的优化甚至删除了“0x11223344”的声明,并直接在代码中使用它。
总而言之,我能以某种方式“强制”编译器避免“数据”与arm64中的立即值代码混合吗?

3b6akqbq

3b6akqbq1#

我发现用“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

相关问题