SSE 系列指令编码
[legacy prefix] [SIMD prefix] [REX prefix] <escape_prefix> <opcode> <ModRM> [SIB] [displacement] [imm8] |
上面是 SSEx 系列的指令编码格式
其中红色部分:escape prefix 、opcode 以及 ModRM 是必需的,
蓝色部分:legacy prefix、SIMD prefix、REX prefix、SIB、displacement 以及 imm8 是可选的。
包括 legacy preifx 与 REX prefix
而 SIMD prefix 实际上属于 opcode 组成部分。
legacy prefix 仅用于对 memory 操作数的修饰,这部分 prefix 是:
关于 address size override prefix 与 segment override prefix,详见:深入了解 prefix
sse 系列指令新增的 SIMD prefix 实际是原来的部分 legacy prefix,它们是:
sse 指令集中的 SIMD prefix,实际上可算是 opcode 的组成部分。
SIMD prefix 与 legacy prefix 都是 legacy prefix
只是在 sse 指令中上面这些 legacy prefix 变成了 SIMD prefix
在 sse 指令中,REX prefix 的作用与通用指令中的 REX prefix 作用是一样的。
在 64 位下,REX prefix 可用来修饰 sse 指令中的 memory 操作数寻址和访问高 8 个 xmm 寄存器。
关于 REX prefix 的细节,详见:REX prefix
escape prefix 与 SIMD prefix 都是 sse 指令中的 opcode 组成部分,用于识别 opcode 码,它们是:
这部分是 sse 指令的 opcode,但是它并不完整,必须由 escape prefix 组合,必要时还需要 SIMD prefix
由 escape prefix 及 SIMD prefix 组合起来的 opcode 才是真正指令 opcode 部分
以下列几条 sse 指令的 opcode
它的完整 opcode 是: 0F E7, 它由 0F(escape prefix)与 E7(opcode)组合而成。
那么,这条指令的最终编码是:0f e7 00 (3 bytes)
这是一条 sse2 指令,它的 opcode 是:66 0f 58 它由 0f(escape prefix)、 66(SIMD prefix)与 58(opcode)组成。
那么,这条指令的最终编码是:66 0f 58 00 (4 bytes)
最后这是一条 Intel 的 SSE4 指令,它的 opcode 是:66 0f 3a 0d
它由 66 -- SIMD prefix 、 0f 3a -- escape prefix 与 0d -- opcode 组成,这个 opcode 共有 4 个 bytes
那么,这条指令最终的编码是:66 0f 3a 0d 00 01 (6 bytes)
通用指令中的 operands 寻址方式都可以用在 sse 指令集中,
sse 指令绝大部分是 2 个 operands 的,一部分是 3 个 operands
由 ModRM 字节的 ModRM.reg 提供对 registers 的寻址,ModRM.r/m 提供 memory 或 registers 寻址。
当 ModRM.mod = 11 时,ModRM.reg 与 ModRM.r/m 分别提供的 first operand 和 second operand 都是 registers 寻址。
当 ModRM.mod ≠ 11 时,first operand 与 second operand 其中一个是 memory 操作数。
使用 REX prefix 能访问扩展的 8 个 registers
关于 ModRM 详见: ModRM 寻址模式
(2)SIB 字节提供 memory 寻址
和通用指令的 SIB 作用一样,负责对 memory 操作数进行寻址。
关于 SIB 详见:SIB 补充寻址
由 imm8 字节提供最后一个 operand 寻址,但指令只有 2 个 operands 时,它提供 second operand 寻址。
下面是 sse4 指令集其中的一条指令的寻址描述:
blendpd xmm1, xmm2/m128, imm8 |
这里举一些具代表性的 sse 指令作为示例,观察它们的编码如何构成。
paddb mm0, mm1 paddb mm0, [eax] |
第 1 条指令两个 operands 都是 mmx 寄存器,那么它的编码是:0f fc c1
0f |
fc |
11 |
000 |
001 |
escape prefix |
opcode |
mod |
reg |
r/m |
ModRM = c1 |
第 2 个条指令的 second operand 是 memory 操作数,它的编码是:0f fc 00
0f |
fc |
00 |
000 |
000 |
escape prefix |
opcode |
mod |
reg |
r/m |
ModRM = 00 |
addpd xmm0, xmm10 addpd xmm10, [r9] |
第 1 条指令的 operand 是 registers,它的编码结构如下:
66 |
0100 |
0 |
0 |
0 |
1 |
0f
|
58
|
11 |
000 |
010 |
SIMD prefix |
4 |
W |
R |
X |
B |
escape prefix |
opcode |
mod |
reg |
r/m |
REX prefix = 41 |
ModRM = c2 |
它最终的编码是:66 41 0f 58 c2
第 2 条指令的 second operand 是 memmory,它的编码结构如下:
66 |
0100 |
0 |
1 |
0 |
1 |
0f
|
58
|
00 |
010 |
001 |
SIMD prefix |
4 |
W |
R |
X |
B |
escape prefix |
opcode |
mod |
reg |
r/m |
REX prefix = 45 |
ModRM = 11 |
它最终的编码是:66 45 0f 58 11
blendpd xmm8, [rax + r10 * 8 + 0x11223344], 1 |
它的 first operand 是 register,second opernad 是 memory,third operand 是 immediate,它的编码结构如下:
66 |
0100 |
0 |
1 |
1 |
0
|
0f 3a
|
0d
|
10 |
000 |
100 |
11 |
010 |
000 |
44 33 22 11 |
01 |
SIMD prefix |
4 |
W |
R |
X |
B |
escape prefix |
opcode |
mod |
reg |
r/m |
scale |
index |
base |
displacement |
imm8 |
REX prefix = 46 |
ModRM = 84 |
SIB = d0 |
它的最终编码是:66 46 0f 3a 0d 84 d0 44 33 22 11 01 (12 bytes)
mik 写于 2009-05-17 00:38