Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly xmm8寄存器值是否在调用之间保留?_Assembly_Visual C++_X86 64_Cpu Registers_Abi - Fatal编程技术网

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

Assembly xmm8寄存器值是否在调用之间保留?,assembly,visual-c++,x86-64,cpu-registers,abi,Assembly,Visual C++,X86 64,Cpu Registers,Abi,使用Visual Studio 2017编译的我的Windows程序执行以下操作: 调用具有值为35.05的默认参数的例程 通过C接口初始化Java虚拟机 再次调用具有值为35.05的默认参数的例程 在第一个调用中,默认参数获得正确的35.05。在第二个调用中,该值是垃圾 我查看了生成的程序集,在第一次调用过程中,使用默认参数35.05从内存位置复制到xmm8,并复制到堆栈(它是第5个参数),然后调用: 0033d 48 8b 01 mov rax, QWORD PTR

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

  • 调用具有值为35.05的默认参数的例程
  • 通过C接口初始化Java虚拟机
  • 再次调用具有值为35.05的默认参数的例程
在第一个调用中,默认参数获得正确的35.05。在第二个调用中,该值是垃圾

我查看了生成的程序集,在第一次调用过程中,使用默认参数35.05从内存位置复制到
xmm8
,并复制到堆栈(它是第5个参数),然后调用:

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
值将被保留。

从中总结的Windows x64调用约定

RCX
RDX
R8
R9
用作输入整数参数
XMM0L
XMM1L
XMM2L
XMM3L
是输入浮点参数
RAX
R10
R11
XMM4
XMM5
都是易变的。所有其他组件,包括
XMM8
都是非易失性的

注意,“调用者/被调用者保存的寄存器”子页面现在有点误导,因为它不包括SSE寄存器


更新:默认情况下,新指令集的任何附加寄存器都是可变的。这包括
YMM0-15
ZMM0-15
的上部,以及
?MM16-31
(如果存在)。

因此,如果JVM真的破坏了
xmm8
,那么它就有故障了。谢谢。那份文件没有出现在我所有的谷歌搜索中:(JavaM是这个?Oracle),如果它接受Windows X64使用的寄存器中的ARG,但是CulbBes寄存器不应该,这听起来是坏的。自定义调用约定是可能的,但是与编译的C/C++不可能的,如果没有ASM包装器,听起来这可能是一个无意的调用约定差异,即JVM中的错误。@PeterCordes是的,Oracle和他们已经接受并修复了。我应该提到我使用的是Java 1.8。值得一提的是,ymm6..15和zmm6..31的高位通道被称为clobbered。严格来说,只有xmm6..15(低位128位)保留调用。使用AVX512VL,我认为即使是xmm16..31也可能被破坏。我不确定这些额外的寄存器如何,但它们可能是易失性的。我将看看是否可以追踪到某人…创建ABI时不存在的任何内容都是易失性的,因为如果不这样做,则是一个后兼容问题。