RTC*_*222 5 x86 assembly machine-code avx512
EVEX.z 位在 AVX-512 中与 k 寄存器结合使用以控制屏蔽。如果 z 位为 0,则为合并屏蔽,如果 z 位为 1,则 k 寄存器中的零元素在输出中为零。
语法如下所示:
VPSUBQ zmm0{k2}{z},zmm1,zmm2
Run Code Online (Sandbox Code Playgroud)
其中 {z} 代表 z 位。
但是如何设置或测试 EVEX.z 位?我搜索了我能找到的所有资源,但没有找到答案。
据我了解,它们的意思是VPSUBQ zmm0{k2}{z},zmm1,zmm2和
VPSUBQ zmm0{k2},zmm1,zmm2是两个不同的指令,其编码在单个位上有所不同,称为“z 位”。(它特别是指令的 EVEX 前缀的一部分。 维基百科记录了所有字段)
因此,您通过{z}在汇编源代码中指定来“设置 z 位” ,告诉汇编器生成具有相应位设置的指令。这在很多地方都有记录,例如英特尔的第 2 卷指令集手册,以及英特尔的内在函数指南,其中包含大多数内在函数的掩码(合并掩码)与掩码(零掩码)版本)
它不是CPU 状态中的物理位,如方向标志或其他东西,它会从一条指令持续到下一条指令。“测试”它没有意义。
为了说明,这是我通过组装两个版本得到的:
00000000 62F1F5CAFBC2 vpsubq zmm0{k2}{z},zmm1,zmm2
00000006 62F1F54AFBC2 vpsubq zmm0{k2},zmm1,zmm2
Run Code Online (Sandbox Code Playgroud)
请注意,编码在第四个字节的高位有所不同。那是你的“z bit”。
也许你在想你可以在运行时“设置”或“清除”z位,从而改变后续指令的屏蔽效果?由于它是每条指令编码的一部分,而不是 CPU 状态,因此这种思维方式仅在您动态 JIT 指令或使用自修改代码时才有效。
在“正常”的提前代码中,您必须在两个版本中编写代码,一次有{z}指令,一次没有。使用条件跳转来决定执行哪个版本。