Visual Studio 2022, Can I control how the immediate values are generated for arm64 compilation?

57 Views Asked by At

When I have the following code:

int value2 = 0x11223344;

The VS2022 compiler (arm64) generates:

StarFunction PROC 

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

ret 

|value_label|
    DCD         0x11223344 

ENDP

As you can see, the value 0x11223344 is generated as "data" at the end of the function.

Is there any way to have some control on that so it generates instead:

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

I cannot use compiler optimizations as I need to have control over the generated code to patch specific code sequences. With compiler optimizations, I loose that control.

I have tried different compiler optimization switches but some of them have no effect and other more aggressive optimizations even remove the declaration of "0x11223344" and directly use it in code afterwards.

Summing up, can I "force" somehow the compiler to avoid that "data" mixed with code for immediate values in arm64?

1

There are 1 best solutions below

2
raff On

I found that declaring the local variables with "volatile" such as:

void MyFunction()
{
   volatile int i = 0x1123344;

   // some code here
}

And also compiling with /Ox, makes the compiler generate the wanted mov Wn, imm16_low; movk Wn, imm16_high, lsl 16 at the expected location where it was declared.

Here is a full example (compiled with /Ox)

int TestFunction()
{
    volatile int a = 0x11223344;
    volatile int b = 0x77887788;
    return 0;
}

Generates:

|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