Assembly xmm8寄存器值是否在调用之间保留?
使用Visual Studio 2017编译的我的Windows程序执行以下操作: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
- 调用具有值为35.05的默认参数的例程
- 通过C接口初始化Java虚拟机
- 再次调用具有值为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时不存在的任何内容都是易失性的,因为如果不这样做,则是一个后兼容问题。