0

ROUNDSS这样的一些 x86 指令需要这种看似晦涩的指令操作数编码,我在英特尔的软件开发人员手册中找不到任何文档或定义。

这种编码的位是如何使用的?我将66 0f 3a 0b c0 0c( roundsd xmm0,xmm0,0xc ) 放入了一个反汇编器并改变了位以获得更好的理解,但只能访问一半的 XMM 寄存器。

我也不清楚

128 位传统 SSE 版本:第一个源操作数和目标操作数相同。

例如66 0f 3a 0b c1 0c,在没有警告/错误的情况下将其反汇编为roundsd xmm0,xmm1,0xc.

4

1 回答 1

2

传统编码

编码如下:

66 0F 3A 0A /r ib

操作码0A0F 3A操作码平面中。66必须提供强制性前缀。操作码后跟一个 modr/m 字节 ( /r),对 R 字段中的第一个操作数和 R/M 字段中的第二个操作数进行编码。该指令后跟一个 8 位立即数 ( ib) 编码第三个操作数。

例如,让我们编码

roundss xmm8, [rdx+r9*8+64], 0xc

我们将xmm8and作为“高位”寄存器,因此必须提供r9REX.RX 前缀来保存额外的位。46

modr/m 字节44表示 8 位位移 (mod = 01),存在 SIB 字节 (r/m = 100),并xmm8作为 reg 操作数 (reg = 000, REX.R set)。

SIB 字节CA指示rdx为基数 (base = 010)、r9索引 (index = 001, REX.X set) 和 8 (scale = 11) 的比例。

然后是位移40(即十进制64)。

最后,我们有 8 位立即数0c

然后这些位按传统前缀、REX 前缀、操作码平面前缀、操作码、modr/m 字节、SIB 字节、位移、立即数的顺序组装。所以整个指令出来为

66 46 0F 3A 0A 44 CA 40 0C
|  |  |     |  |  |  |  \... immediate
|  |  |     |  |  |  \...... displacement
|  |  |     |  |  \......... SIB byte
|  |  |     |  \............ modr/m byte
|  |  |     \............... opcode
|  |  \..................... opcode plane prefix
|  \........................ REX prefix
\........................... mandatory prefix

VEX 编码

128 位传统 SSE 版本:第一个源操作数和目标操作数相同。

指令的 VEX 编码变体vroundss有一个额外的源操作数。旧版编码版本不是这个操作数,而是从目标操作数读取这个源操作数。

如果我们想将此指令编码为 VEX 编码的变体

vroundss xmm8, xmm2, [rdx+r9*8+64], 0xc

相反,我们以 VEX 前缀开始。该前缀将强制前缀、REX 前缀和操作码平面前缀包含在一个 3 字节前缀中。此前缀具有以下形式:

11000100 RXBmmmmm WvvvvLpp
R, X, B: complemented REX prefix bits
W: REX.W prefix bit (not complemented)
m: opcode plane (1: `0F`, 2: `0F 38`, 3: `0F 3A`)
L: vector length (0: 128 bit, 1: 256 bit)
p: mandatory prefix (0: none, 1: `66`, 2: `F3`, 3: `F2`)
v: complemented extra source register number

较短的 2 字节 VEX 前缀

11000101 RvvvvLpp

可以在 REX.X、REX.B 和 REX.W 清晰且 m = 00000 时使用。这里不是这种情况。编码为

VEX.LIG.66.0F3A.WIG 0A /r ib VROUNDSS xmm1, xmm2, xmm3/m32, imm8

表示忽略 L 和 W 字段,有一个强制66前缀并且操作码0A0F 3A操作码平面中,后跟 modr/m 操作数和一个字节立即数。第一个和第三个操作数以 modr/m 字节编码,第二个操作数是由 VEX 前缀编码的附加操作数。

所以我们有我们的指示

R = 0, indicating presence of REX.R
X = 0, indicating presence of REX.X
B = 1, indicating absence  of REX.B
W = 0, indicating absence  of REX.W (ignored)
L = 0, indicating a 128 bit operand size (ignored)
m = 00010, indicating the 0F 3A opcode plane
p = 01, indicating a 66 mandatory prefix
v = 1101, indicating xmm2 as a first operand

给出 VEX 前缀C4 22 69。其余部分与传统编码相同,提供完整指令

C4 23 69 0A 44 CA 40 0C
|        |  |  |  |  \... immediate
|        |  |  |  \...... displacement
|        |  |  \......... SIB byte
|        |  \............ modr/m byte
|        \............... opcode
\........................ VEX prefix
于 2022-01-02T12:36:43.683 回答