问题描述
据我所知,从 AVX 开始,通过 3 字节 VEX 或 EVEX 前缀,您可以在 64 位模式下编码多达 32 个 XMM/YMM/ZMM 寄存器,但是当查看英特尔手册时告诉你这是可能的,我找不到它解释实际如何发生的部分。我只能看到一个扩展字段,即 REX 反转字段,但除了 EVEX 前缀中用于编码掩码寄存器的特殊位置之外,没有其他任何内容。
您需要在某处使用 2 位来编码这么多寄存器。您是否必须以某种方式将 VEX/EVEX 前缀中的 2 个反向 REX 字段组合起来,或者这个过程是如何工作的?
解决方法
xmm16..31(以及它们的 ymm/zmm 等价物)是 AVX-512 的新特性,只能通过 EVEX 前缀访问,其中有 2 额外位要添加到每个 ModRM 字段,以及另外 5 位作为第三个操作数的额外字段。
REX + legacy-SSE,以及用于 AVX1/2 编码的 VEX,只能访问 xmm/ymm0..15。
Wikipedia's EVEX article 有一个很好的表格,显示了这些位的来源,我转录了其中的一些:
地址模式 | 第 4 位 | 第 3 位 | 位 [2:0] | 注册类型 |
---|---|---|---|---|
注册 | EVEX.R' | EVEX.R | ModRM.reg | 通用,矢量 |
RM | EVEX.X | EVEX.B | ModRM.r/m | 探地雷达,矢量 |
NDS/NDD | EVEX.V' | EVEX.v3 | EVEX.v2v1v0 | 矢量 |
基础 | 0 | EVEX.B | SIB.base(或 modrm) | 探地雷达 |
索引 | 0 | EVEX.X | SIB.index | 探地雷达 |
如果 R/M 操作数是向量寄存器而不是内存寻址模式,则它同时使用 X(索引)和 B(基)位作为额外的寄存器编号位。因为这意味着没有 SIB.index 字段,它也可能需要扩展才能选择 r8..r15。
在 REX 和 VEX 前缀中,当源操作数不是具有索引寻址模式的内存时,X 位不再使用。 (https://wiki.osdev.org/X86-64_Instruction_Encoding#REX_prefix,但请注意该页面前面的寄存器编号表中显示 X.Reg、X is just a placeholder for R or B,not REX.X;该页面上的选项令人困惑)。
另请参阅 x86 BSWAP instruction REX doesn't follow Intel specs? 以获取使用来自 REX 前缀的额外寄存器编号位的另一个图表。