xmm8寄存器值是否在调用之间保留?

时间:2018-12-11 22:59:51

标签: assembly visual-c++ x86-64 cpu-registers abi

我使用Visual Studio 2017编译的Windows程序执行以下操作:

  • 调用一个例程,该例程的默认参数值为35.05。
  • 通过C接口初始化Java虚拟机
  • 再次调用该例程,该例程的默认参数值为35.05。

在第一次调用中,默认参数获得正确的35.05。在第二个调用中,该值是垃圾。

我查看了生成的程序集,并在第一次调用时将默认参数35.05从内存位置复制到xmm8并将其复制到堆栈(这是第5个参数),并进行了调用: / p>

0033d   48 8b 01     mov     rax, QWORD PTR [rcx]
00340   41 b8 14 00 00
00       mov     r8d, 20 // a default argument
00346   f3 44 0f 10 05
00 00 00 00  movss   xmm8, DWORD PTR __real@420c3333 // this is 35.05
0034f   f3 44 0f 11 44
24 28        movss   DWORD PTR [rsp+40], xmm8
00356   48 c7 44 24 20
1e 00 00 00  mov     QWORD PTR [rsp+32], 30 // a default argument
0035f   45 8d 48 05  lea     r9d, QWORD PTR [r8+5]
00363   b2 0f        mov     dl, 15 // a default argument
00365   ff 90 08 01 00
00       call    QWORD PTR [rax+264]

然后进行调用以初始化JVM。

然后用于下一次调用xmm8再次将值复制到堆栈:

00ce8   48 8b 01     mov     rax, QWORD PTR [rcx]
00ceb   41 b8 14 00 00
00       mov     r8d, 20
00cf1   f3 44 0f 11 44
24 28        movss   DWORD PTR [rsp+40], xmm8
00cf8   48 c7 44 24 20
1e 00 00 00  mov     QWORD PTR [rsp+32], 30
00d01   45 8d 48 05  lea     r9d, QWORD PTR [r8+5]
00d05   b2 0f        mov     dl, 15
00d07   ff 90 08 01 00
00       call    QWORD PTR [rax+264]

但是现在xmm8已被覆盖。

如果我取消了初始化JVM的调用,那么该值将保留。

问题是,谁错了? JVM没有保留该值,或者Microsoft编译器错误地假定xmm8的值将被保留。

1 个答案:

答案 0 :(得分:3)

根据Microsoft docs总结的Windows x64调用约定。

RCXRDXR8R9用作输入整数参数。 XMM0LXMM1LXMM2LXMM3L是输入浮点参数。 RAXR10R11XMM4XMM5是易失的。包括XMM8在内的所有其他非易失性存储器。

  

请注意,“呼叫者/被呼叫者保存的寄存器”子页面目前有点误导,因为它不包括SSE寄存器。

更新:默认情况下,用于较新指令集的所有其他寄存器都是易失性的。这包括YMM0-15ZMM0-15的上半部分,以及?MM16-31(如果有)的上半部分。