在英特尔 x64 手册中,它说在 32 位 SSE2 模式下有 XMM 寄存器 0-7。那么为什么使用这些寄存器的指令中有 95% 会跳过 0 而使用 1-4?
你误解了什么,可能是手册中的占位符。当指令描述说
xmm1
或 xmm2
时,它通常表示任何 xmm 寄存器,数字仅表示操作数编号。
例如
ADDPS xmm1, xmm2/m128
可以将两个任意的xmm寄存器相加或者向任意一个xmm寄存器中添加一个内存操作数。
英特尔手册中的编号是占位符,如第一个xmm操作数,而不是寄存器编号。
查看
blendvps
的一种情况,其中 XMM0 是一个操作数的唯一选择,而不是占位符,对于非 AVX 版本:https://felixcloutier.com/x86/blendvps.
操作码 | 说明 | 开/关 |
---|---|---|
|
|
RM0 |
|
|
RVMR |
|
|
RVMR |
注意尖括号内的全大写
<XMM0>
:这就是英特尔在表示需要特定寄存器时所写的内容。(在机器代码中隐式使用,如 RDX:RAX 用于mul rcx
)
还要注意 Op/En(Operand Encoding)列,它有另一个表的键,“Instruction Operand Encoding”,我们可以在其中看到由 ModR/M(或 VEX)字段编码的寄存器,甚至是一个即时;
vblendvps
有点疯狂。但无论如何,鉴于指令中有位对它们进行编码,很明显它们可以是任何 XMM 寄存器。
开/关 | 操作数 1 | 操作数 2 | 操作数 3 | 操作数 4 |
---|---|---|---|---|
RM0 | ModRM:reg (r, w) | ModRM:r/m (r) | 隐式 XMM0 | NA |
RVMR | ModRM:reg (w) | VEX.vvvv (r) | ModRM:r/m (r) | imm8[7:4] |
(r,w) 与 (w) 或 (r) 告诉您操作数是读、写还是两者。
另见
或者阅读第 2 卷前面的章节,它告诉您如何读取条目:操作数编码表详细说明了一条指令如何指定寄存器。 How to read the Intel Opcode notation notation 有一个答案引用了其中的一些,但实际的 PDF 有示例和内容。