【问题标题】:How does the instruction decoder differentiate between EVEX prefix and BOUND opcode in 32-bit mode?指令解码器如何区分 32 位模式下的 EVEX 前缀和 BOUND 操作码?
【发布时间】:2018-07-28 22:11:57
【问题描述】:

在 32 位模式下,Intel 通过反转寄存器扩展的高位来解决 VEX 前缀与 LDS/LES 冲突,因为 ModRM 字节的 mod 字段不能为 11b

VEX 前缀的初始字节值 C4h 和 C5h 与 LDS 和 LES 指令的操作码相同。 64 位模式不支持这些指令。为了解决在 32 位模式下的歧义,VEX 的规范利用了这样一个事实,即合法的 LDS 或 LES 的 ModRM 字节不能是 11xxxxxx 形式(它将指定一个寄存器操作数)。 VEX 前缀的第二个字节中的各种位域被反转,以确保该字节在 32 位模式下始终是这种形式。

https://en.wikipedia.org/wiki/VEX_prefix#Technical_description

但是在 EVEX 中,R 和 X 位没有反转,这导致 mod=00b,这也表示 BOUND 指令中的内存操作数

来自 REX 前缀的四位 R、X、B 和 W。 W 将操作数大小扩展为 64 位或用作附加操作码,R 扩展 reg,B 扩展 r/m 或 reg,X 和 B 扩展 SIB 字节中的索引和基数。 与 VEX 前缀相比,RXB 以非反转形式提供,就像在 REX 前缀中一样。

https://en.wikipedia.org/wiki/EVEX_prefix

那么他们如何干净利落地解码重叠的指令呢?


我查看了英特尔手册,他们似乎只提到了 VEX 中的位反转,而不是 EVEX。

OTOH sandpile 中的表格说 EVEX 中的那些 RXB 位也应该反转。

哪一个是正确的?

【问题讨论】:

  • 这很有趣,如果我用 EVEX 组装一些指令,它们会输出 RXB 反转,这当然适用于 bound。但是手册似乎没有说要这样做..
  • R & X 位不用于 32 位模式,因此可能必须将这些位设置为 1 以避免创建有效的 BOUND 指令。
  • @RossRidge 即使在 64 位模式下,它们也会被反转。至少nasm 这么认为,必须在实际的 cpu 上进行测试。

标签: assembly x86 instructions opcode


【解决方案1】:

反转位的技巧之所以奏效,是因为有两个事实:

  1. 在 32 位模式下,32 个 ZMM 寄存器中只有 8 个可用,因此 EVEX.R' 位永远不会翻转,因此永远不会使用允许的 BOUND 编码产生别名。
  2. 在 64 位模式下,无法识别 BOUND 指令,因此 EVEX 位可以采用任何值。

AVX 上patent 的摘录阐明了这一点:

[0111] REX' 字段 — 这是 REX' 字段的第一部分,是 EVEX.R' 位字段(EVEX 字节 1,位 [4]-R'),用于编码扩展 32 个寄存器集。在本发明的一个实施例中,该位以及如下所示的其他位以位反转格式存储以区别(在众所周知的 x86 32 位模式中)与实际操作码字节为 62 的 BOUND 指令区分开来,但在 MOD R/M 字段(如下所述)中不接受 MOD 字段中的值 11;本发明的替代实施例不以反转格式存储该位和以下其他指示的位。值 1 用于对低 16 个寄存器进行编码。也就是说,R'Rrrr 是由 EVEX.R'、EVEX.R 和其他字段中的其他 RRR 组合而成的。

然而,Intel SDM 并不清楚这一事实。 我查看了 SDM,确实,在 EVEX 部分中没有提到 EVEX 编码的补码含义的痕迹。人们必须以某种方式从 EVEX 是 VEX 的扩展这一事实中推断出它,而对于后者,有一个反向含义的陈述(第 2A 卷,第 2.3.5 节,第一个项目符号):

该字段使用 1 的补码形式(反转形式)编码,即 XMM0/YMM0/R0 编码为 1111B,XMM15/YMM15/R15 编码为 0000B。

【讨论】:

  • 你误读了我的问题。英特尔手册和 wiki 文章没有说前 2 位是倒置的,所以它会与 BOUND 编码发生冲突。这就是我想知道的。那些是 R 和 X,而不是 R'。此外,您只能在 32 位模式下访问 8 个 ZMM 寄存器,而不是 16 个
  • 同一专利还说“EVEX.R、EVEX.X 和 EVEX.B 位字段提供与相应 VEX 位字段相同的功能,并使用 1s 补码形式编码,即 ZMM0编码为1111B,ZMM15编码为0000B。指令的其他字段编码寄存器索引的低三位,如本领域已知的(rrr、xxx和bbb),使得Rrrr、Xxxx和Bbbb可以是通过添加 EVEX.R、EVEX.X 和 EVEX.B 形成。"
  • @LưuVĩnhPhúc 谢谢,我不确定是 8 还是 16。我查看了 SDM,确实,在 EVEX 部分中没有提到 EVEX 编码的补码含义的痕迹.人们必须以某种方式从 EVEX 是 VEX 的扩展这一事实中推断出来,对于后者,有一个反转含义的陈述(第 2A 卷,第 2.3.5 节,第一个项目符号):“该字段使用 1 的补码形式编码(倒转形式),即XMM0/YMM0/R0编码为1111B,XMM15/YMM15/R15编码为0000B。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-04
  • 2014-02-05
  • 2015-09-17
  • 2013-07-26
  • 2012-10-21
相关资源
最近更新 更多