intel白皮书卷2 附录A(AI翻译)
操作码映射表是按照。
A.1 使用操作码表(Using Opcode Tables)
本附录中的表格列出了各条指令的操作码(包括必须的指令前缀以及由 ModR/M 字节提供的操作码扩展)。
表格中的空白单元表示该操作码是保留的(reserved)或未定义的(undefined)。
操作码映射表是按照操作码字节高 4 位和低 4 位的十六进制值来组织的。
-
1 字节操作码编码(表 A-2)
使用操作码的高 4 位作为行索引,低 4 位作为列索引,在操作码表中查找对应指令。 -
以
0FH开头的 2 字节操作码(表 A-3)
跳过所有指令前缀以及0FH字节(0FH之前可能带有66H、F2H或F3H前缀),
然后使用下一个操作码字节的高 4 位和低 4 位分别作为行和列索引。 -
以
0F38H或0F3AH开头的 3 字节操作码(表 A-4)
跳过所有指令前缀以及0F38H或0F3AH,
再使用第三个操作码字节的高 4 位和低 4 位来索引表中的行和列。
关于一字节、两字节和三字节操作码的查表示例,请参见
A.2.4 节《一字节、两字节和三字节操作码的查找示例》。
当 ModR/M 字节提供操作码扩展时,该信息会对操作码的执行进行限定。
有关 ModR/M 字节中的操作码扩展如何修改表 A-2 和表 A-3 中的操作码映射,请参见 A.4 节。
用于浮点指令的 转义(ESC)操作码表在每一页的顶部标识了操作码的 高 8 位。
请参见 A.5 节。
如果随附的 ModR/M 字节位于 00H–BFH 范围内,则由:
- ModR/M 的 reg 位
- 以及 位 3–5(每页第三张表的顶行)
共同决定具体操作码。
如果 ModR/M 字节超出 00H–BFH 的范围,则由该节中每页底部的两张表进行映射。
A.2 缩写说明(Key to Abbreviations)
操作数使用一种 Zz 形式的两字符代码进行标识:
- 第一个字符(大写字母):表示寻址方式(addressing method)
- 第二个字符(小写字母):表示操作数类型(operand type)
A.2.1 寻址方式代码(Codes for Addressing Method)
下列缩写用于描述指令操作数的寻址方式(addressing method):
| 代码 | 含义说明 |
|---|---|
| A | 直接地址:指令中没有 ModR/M 字节,操作数地址直接编码在指令中。不能使用基址寄存器、变址寄存器或比例因子(例如:远跳转 JMP (EA))。 |
| C | ModR/M 字节中的 reg 字段选择一个控制寄存器(例如:MOV (0F20, 0F22))。 |
| D | ModR/M 字节中的 reg 字段选择一个调试寄存器(例如:MOV (0F21, 0F23))。 |
| E | 操作码后跟一个 ModR/M 字节,用于指定操作数。操作数可以是通用寄存器或内存地址。若为内存地址,则由段寄存器以及以下元素计算得出:基址寄存器、变址寄存器、比例因子、位移。 |
| F | EFLAGS / RFLAGS 寄存器。 |
| G | ModR/M 字节中的 reg 字段选择一个通用寄存器(例如:AX (000))。 |
| H | VEX 前缀中的 VEX.vvvv 字段选择一个 128 位 XMM 或 256 位 YMM 寄存器(由操作数类型决定)。在传统 SSE 编码中该操作数不存在,此时指令会变为破坏式(destructive)形式。 |
| I | 立即数:操作数的值直接编码在指令的后续字节中。 |
| J | 指令中包含一个相对偏移量,该偏移量会加到指令指针寄存器中(例如:JMP (E9)、LOOP)。 |
| L | 8 位立即数的高 4 位选择一个 128 位 XMM 或 256 位 YMM 寄存器(由操作数类型决定)。在 32 位模式下最高位被忽略。 |
| M | ModR/M 字节只能引用内存操作数(例如:BOUND、LES、LDS、LSS、LFS、LGS、CMPXCHG8B)。 |
| N | ModR/M 字节中的 R/M 字段选择一个 MMX 技术的 packed-quadword 寄存器。 |
| O | 指令中没有 ModR/M 字节。操作数的偏移量以 word 或 double word(取决于地址大小属性)的形式直接编码在指令中。不能使用基址寄存器、变址寄存器或比例因子(例如:MOV (A0–A3))。 |
| P | ModR/M 字节中的 reg 字段选择一个 MMX 技术的 packed-quadword 寄存器。 |
| Q | 操作码后跟一个 ModR/M 字节,用于指定操作数。操作数可以是 MMX 寄存器或内存地址。若为内存地址,则由段寄存器以及基址寄存器、变址寄存器、比例因子和位移共同计算。 |
| R | ModR/M 字节中的 R/M 字段只能引用通用寄存器(例如:MOV (0F20–0F23))。 |
| S | ModR/M 字节中的 reg 字段选择一个段寄存器(例如:MOV (8C, 8E))。 |
| U | ModR/M 字节中的 R/M 字段选择一个 128 位 XMM 或 256 位 YMM 寄存器(由操作数类型决定)。 |
| V | ModR/M 字节中的 reg 字段选择一个 128 位 XMM 或 256 位 YMM 寄存器(由操作数类型决定)。 |
| W | 操作码后跟一个 ModR/M 字节,用于指定操作数。操作数可以是 128 位 XMM 寄存器、256 位 YMM 寄存器(由操作数类型决定),或内存地址。若为内存地址,则由段寄存器、基址寄存器、变址寄存器、比例因子和位移共同计算。 |
| X | 由 DS:rSI 寄存器对寻址的内存(例如:MOVS、CMPS、OUTS、LODS)。 |
| Y | 由 ES:rDI 寄存器对寻址的内存(例如:MOVS、CMPS、INS、STOS、SCAS)。 |
A.2.2 操作数类型代码(Codes for Operand Type)
下列缩写用于描述指令操作数的类型(operand type):
| 代码 | 含义说明 |
|---|---|
| a | 两个内存操作数:根据操作数大小属性(operand-size attribute),表示两个 word 内存操作数或两个 doubleword 内存操作数(仅用于 BOUND 指令)。 |
| b | 字节(byte),与操作数大小属性无关。 |
| c | 字节或字(byte / word),取决于操作数大小属性。 |
| d | 双字(doubleword),与操作数大小属性无关。 |
| dq | 双四字(double-quadword),与操作数大小属性无关。 |
| p | 指针类型:32 位、48 位或 80 位指针,取决于操作数大小属性。 |
| pd | 128 位或 256 位 打包的 双精度浮点数据(packed double-precision floating-point)。 |
| pi | 四字(quadword)MMX 技术寄存器(例如:mm0)。 |
| ps | 128 位或 256 位 打包的 单精度浮点数据(packed single-precision floating-point)。 |
| q | 四字(quadword),与操作数大小属性无关。 |
| 双四字(Quad-Quadword,256 位),与操作数大小属性无关。 | |
| s | 伪描述符(pseudo-descriptor),长度为 6 字节或 10 字节。 |
| sd | 128 位双精度浮点向量中的标量元素(scalar double-precision)。 |
| ss | 128 位单精度浮点向量中的标量元素(scalar single-precision)。 |
| si | 双字整数寄存器(例如:eax)。 |
| v | 字 / 双字 / 四字(64 位模式),取决于操作数大小属性。 |
| w | 字(word),与操作数大小属性无关。 |
| x | 根据操作数大小属性,表示 dq 或 qq。 |
| y | 双字 / 四字(64 位模式),取决于操作数大小属性。 |
| z | 当操作数大小为 16 位 时表示 word;当操作数大小为 32 位或 64 位 时表示 doubleword。 |
A.2.3 寄存器代码(Register Codes)
当某条指令要求使用特定寄存器作为操作数时,寄存器会直接以名称标识
(例如:AX、CL、ESI)。
寄存器名称本身就表明了该寄存器的位宽是 64 位、32 位、16 位还是 8 位。
当寄存器的位宽**取决于操作数大小属性(operand-size attribute)**时,会使用eXX 或 rXX 形式的寄存器标识符:
eXX:用于 16 位或 32 位 两种可能的情况rXX:用于 16 位、32 位或 64 位 三种可能的情况
例如:
-
eAX- 操作数大小为 16 位 → 使用
AX - 操作数大小为 32 位 → 使用
EAX
- 操作数大小为 16 位 → 使用
-
rAX- 可能表示
AX、EAX或RAX(取决于操作数大小属性)
- 可能表示
当使用 REX.B 位 来修改操作码中 reg 字段所指定的寄存器时,
会在寄存器名称后面加上 “/x”,以表示存在额外的寄存器可能性。
例如:
rCX/r9
表示该寄存器既可能是rCX,也可能是r9。
需要注意的是:
在这种情况下,r9 的位宽同样由操作数大小属性决定,
其规则与 rCX 完全一致。
A.2.4 一字节、两字节和三字节操作码的查找示例
(Opcode Look-up Examples for One, Two, and Three-Byte Opcodes)
本节通过示例说明如何使用操作码映射表来查找指令操作码。
A.2.4.1 一字节操作码指令(One-Byte Opcode Instructions)
一字节操作码的操作码映射表见 表 A-2。
该表按照以下方式组织:
- 行(row):操作码十六进制值的 低 4 位
- 列(column):操作码十六进制值的 高 4 位
操作码表中的每一个表项,属于以下两种类型之一:
- 使用 A.2 节中定义的记号表示的指令助记符及其操作数类型
- 用作**指令前缀(instruction prefix)**的操作码
一字节操作码后续字节的解释规则
对于操作码映射表中对应具体指令的表项,主操作码后续字节的解释规则属于以下几种情况之一:
-
需要 ModR/M 字节
ModR/M 字节按照 A.1 节 以及
《Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A》
第 2 章 Instruction Format 中定义的规则进行解释。
操作数类型使用 A.2 节中定义的记号。 -
需要 ModR/M 字节,且 reg 字段作为操作码扩展
此时 ModR/M 字节中的 reg/opcode 字段用于区分具体指令。
解释该 ModR/M 字节时应使用 表 A-6。 -
ModR/M 字节的使用是保留或未定义的
该情况适用于:- 表示指令前缀的表项
- 不带操作数、且不使用 ModR/M 的指令
(例如:60H→PUSHA,06H→PUSH ES)
示例 A-1:一字节操作码的查找示例
(Look-up Example for 1-Byte Opcodes)
给定操作码:
03 05 00 00 00 00
这是一个 ADD 指令,其解释过程如下(使用表 A-2):
-
定位操作码
- 操作码的第一个十六进制数字 0 → 表示表中的行
- 第二个十六进制数字 3 → 表示表中的列
由此定位到一个 ADD 指令(两个操作数)。
-
解析操作数类型
- 第一个操作数类型为 Gv
→ 表示一个通用寄存器,其大小为 word 或 doubleword,取决于操作数大小属性。 - 第二个操作数类型为 Ev
→ 表示后面跟随一个 ModR/M 字节,该字节指定操作数是:- 一个 word / doubleword 通用寄存器,或
- 一个内存操作数。
- 第一个操作数类型为 Gv
-
解析 ModR/M 字节
- ModR/M 字节为
05H
→ 表示后面跟随一个 32 位位移量(00000000H)。 - ModR/M 字节中的 **reg/opcode 字段(位 3–5)**为
000
→ 指定寄存器为 EAX。
- ModR/M 字节为
最终,该操作码对应的指令为:
ADD EAX, mem_op
其中,内存操作数 mem_op 的偏移量为:
00000000H
说明:Group 指令
部分 一字节和两字节操作码在操作码表中指向一个 组号(Group Number)
(在操作码映射表中以阴影单元格表示)。
组号表示:
该指令使用 ModR/M 字节中的 reg/opcode 位 作为 操作码扩展,
用于区分同一主操作码下的不同指令。
有关详细说明,请参见 A.4 节。
A.2.4.2 两字节操作码指令(Two-Byte Opcode Instructions)
表 A-3 给出了两字节操作码映射表,该表中包含的主操作码可能是:
- 2 字节长度,或
- 3 字节长度
两字节长度的操作码
长度为 2 字节的主操作码以 转义操作码 0FH 开头。
- 使用第二个操作码字节的:
- 高 4 位 → 表示表中的列
- 低 4 位 → 表示表中的行
- 由此在表 A-3 中定位对应的指令。
三字节长度(使用 0FH)的操作码
某些被归类在两字节 opcode 表中的操作码,实际上是 3 字节长度,其形式为:
[mandatory prefix] + 0FH + opcode
其中 mandatory prefix 可能是:
66HF2HF3H
此时:
- 使用第三个字节的高 4 位和低 4 位
- 在表 A-3 中索引行和列
⚠️ 例外情况:
如果第二个操作码字节是38H或3AH,
则该指令属于 三字节 opcode 转义指令,应参见 A.2.4.3。
两字节操作码后续字节的解释规则
对于操作码映射表中的每一个表项,主操作码之后的字节解释规则属于以下情况之一:
-
需要 ModR/M 字节
ModR/M 字节按照 A.1 节以及
《Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A》
第 2 章 Instruction Format 的规则进行解析。
操作数类型使用 A.2 节中的记号。 -
需要 ModR/M 字节,且 reg 字段作为操作码扩展
此时 ModR/M 字节中的 reg/opcode 字段用于区分具体指令,
解释应参考 表 A-6。 -
ModR/M 字节的使用是保留或未定义的
该情况适用于:- 使用 ModR/M 编码、但没有操作数的指令
(例如:0F77H→EMMS)
- 使用 ModR/M 编码、但没有操作数的指令
示例 A-2:两字节操作码查找示例
(Look-up Example for 2-Byte Opcodes)
给定操作码:
0F A4 05 00 00 00 00 03
使用表 A-3 对 SHLD 指令进行查找与解析:
-
定位操作码
- 行:
A - 列:
4
表明该指令是
SHLD,操作数类型为 Ev, Gv, Ib。 - 行:
-
解析操作数
- Ev:ModR/M 字节指定的 word 或 doubleword 操作数
- Gv:ModR/M 字节中的 reg 字段指定一个通用寄存器
- Ib:紧随其后的一个立即数字节
-
解析 ModR/M 字节
- ModR/M =
05H mod与r/m表示:- 使用 32 位位移来定位第一个内存操作数
reg字段指定第二个操作数为 EAX
- ModR/M =
-
解析后续字节
- 接下来的
00000000H:目的操作数的 32 位内存位移 - 最后一个字节
03H:移位次数的立即数
- 接下来的
最终,该操作码表示的指令为:
SHLD DS:00000000H, EAX, 3
A.2.4.3 三字节操作码指令(Three-Byte Opcode Instructions)
表 A-4 与 表 A-5 给出了三字节操作码映射表。
这些表中包含的主操作码可能是:
- 3 字节长度
- 4 字节长度
三字节长度的操作码
长度为 3 字节的主操作码以以下 双转义字节开头之一:
0F38H0F3AH
此时:
- 使用第三个操作码字节的高 4 位和低 4 位
- 在表 A-4 或 A-5 中索引行和列
四字节长度的操作码
长度为 4 字节的主操作码形式为:
[mandatory prefix] + 0F38H / 0F3AH + opcode
其中 mandatory prefix 可以是:
66HF2HF3H
此时:
- 使用第四个字节的高 4 位和低 4 位
- 在表 A-4 或 A-5 中索引行和列
三字节操作码后续字节的解释规则
对于操作码映射表中的每一个表项:
- 必须存在 ModR/M 字节
- ModR/M 的解释规则与 A.1 节以及
Volume 2A 的 Instruction Format 完全一致 - 操作数类型仍然使用 A.2 节中的记号
示例 A-3:三字节操作码查找示例
(Look-up Example for 3-Byte Opcodes)
给定操作码:
66 0F 3A 0F C1 08
使用表 A-5 解析 PALIGNR 指令:
-
前缀与表选择
66H:操作数大小前缀0F 3A:表示使用 表 A-5
-
定位操作码
- 行:
0 - 列:
F
表明该指令为
PALIGNR,操作数类型为 Vdq, Wdq, Ib。 - 行:
-
解析操作数
- Vdq:ModR/M 的 reg 字段选择一个 128 位 XMM 寄存器
- Wdq:ModR/M 的 R/M 字段选择一个 128 位 XMM 寄存器或内存操作数
- Ib:紧随其后的立即数字节
-
解析 ModR/M 字节
- ModR/M =
C1H reg→ 指定第一个操作数为 XMM0mod+r/m→ 指定第二个操作数为 XMM1
- ModR/M =
-
解析立即数
- 最后一个字节
08H:立即数
- 最后一个字节
最终,该操作码表示的指令为:
PALIGNR XMM0, XMM1, 8
A.2.4.4 VEX 前缀指令(VEX Prefix Instructions)
包含 VEX 前缀的指令,是在 两字节和三字节操作码映射表的基础上进行组织的,
其对应关系由 VEX.mmmmm 字段所隐含的转义操作码决定:
mmmm = 00001→ 隐含0Fmmmm = 00010→ 隐含0F38Hmmmm = 00011→ 隐含0F3AH
因此,VEX 编码指令在 opcode 表中的定位方式,与非 VEX 编码指令是类似的:
每个表项仍然基于 opcode 字节的值进行索引。
VEX 前缀的功能位
VEX 前缀包含多个比特字段,用于编码以下信息:
- 隐含的前缀功能(VEX.pp)
- 对应传统前缀:
66H、F2H、F3H
- 对应传统前缀:
- 操作数大小 / opcode 相关信息(VEX.L)
- 用于区分 128 位 与 256 位 向量操作
有关 VEX 前缀各字段的详细说明,请参见 第 4 章。
VEX / 非 VEX 指令在 opcode 表中的表示方式
操作码表 A-2 到 A-6 中同时包含:
- 带 VEX 前缀的指令
- 不带 VEX 前缀的指令
许多表项只列出一次,但实际上同时代表:
- VEX 形式
- 非 VEX 形式
其区分规则如下:
-
存在 VEX 前缀时
- 所有操作数均有效
- 指令助记符通常以前缀
v开头
(例如:VMOVUPD)
-
不存在 VEX 前缀时
- VEX.vvvv 操作数不可用
- 指令助记符中的
v前缀被省略
(例如:MOVUPD)
仅存在于 VEX 形式的指令
有少量指令只存在 VEX 编码形式,
这些指令在操作码表中会用 上标 “v” 进行标记。
VEX 指令的操作数大小判定
VEX 前缀指令的操作数大小,可通过 操作数类型代码(operand type code) 来判断:
dq→ 128 位向量qq→ 256 位向量x→ 支持 128 位或 256 位- 具体大小由 VEX.L 位 决定
例如:
VMOVUPD Vx, Wx
表示:
- 当
VEX.L = 0→ 使用 128 位 - 当
VEX.L = 1→ 使用 256 位
两种形式均被该指令支持。
A.2.5 操作码表中使用的上标说明
(Superscripts Utilized in Opcode Tables)
表 A-1 给出了针对某些特殊编码情况的说明。
这些说明在后续的操作码映射表中通过**上标(superscript)**进行标注。
在操作码表中,灰色单元格表示指令分组(instruction groupings)。
表 A-1:操作码表中使用的上标含义
| 上标符号 | 含义说明 |
|---|---|
| 1A | ModR/M 字节的第 5、4、3 位(即 reg/opcode 字段)用作操作码扩展。参见 A.4 节《一字节与两字节操作码的操作码扩展》。 |
| 1B | 当需要刻意触发非法操作码异常(#UD) 时,应使用:0F 0B(UD2 指令)或 0F B9H 操作码。 |
| 1C | 某些指令共用同一个两字节操作码。 当指令存在变体,或同一操作码对应多条不同指令时, 需通过 ModR/M 字节来区分具体指令。 有关用于区分指令的 ModR/M 取值,请参见 表 A-6。 |
| i64 | 该指令在 64 位模式下非法或不可编码。 注意: 40H–4FH(单字节 INC / DEC)在 64 位模式下会被解释为 REX 前缀组合。在 64 位模式下应使用 FE / FF(Group 4 和 Group 5) 来实现 INC / DEC。 |
| o64 | 该指令仅在 64 位模式下可用。 |
| d64 | 在 64 位模式下,该指令默认使用 64 位操作数大小,且无法编码为 32 位操作数大小。 |
| f64 | 在 64 位模式下,该指令的操作数大小被强制为 64 位。 任何试图改变操作数大小的前缀,在 64 位模式下都会被忽略。 |
| v | 该指令仅存在 VEX 形式,不存在传统的 SSE(legacy SSE)形式。 |
| v1 | 该指令仅存在 VEX128 与 SSE 形式,不存在 VEX256 形式。 当无法仅通过数据大小推断这一点时,会使用该上标进行说明。 |
A.3 一字节、两字节和三字节操作码映射表
(ONE, TWO, AND THREE-BYTE OPCODE MAPS)
一字节、两字节以及三字节操作码的映射表,见下文中的 表 A-2 至 表 A-5。
这些操作码表采用多页形式进行展示。
为了方便查找,在逻辑上具有连续关系的行与列,会被安排在相对的页面上,以减少查表时的翻页成本。
需要注意的是:
- 各个表格页面中不会重复显示表注(footnotes)
- 每一张表对应的完整表注,统一放置在该表的最后一页
因此,在查阅操作码映射表时,
如果遇到上标、分组说明或特殊限制条件,应当查看该表最后一页的表注说明。
Table A-2


注释(NOTES)
- 所有操作码映射表中的空白单元均为保留项(reserved),不得使用。
- 不要依赖任何**未定义(undefined)或保留(reserved)**位置的行为。
Table A-3




注释(NOTES)
- 所有操作码映射表中的空白项均为保留(reserved),不得使用。
- 不要依赖任何**未定义(undefined)或保留(reserved)**位置的行为。
Table A-4


注释(NOTES)
- 所有操作码映射表中的空白项均为保留(reserved),不得使用。
- 不要依赖任何**未定义(undefined)或保留(reserved)**位置的行为。
Table A-5


注释(NOTES)
- 所有操作码映射表中的空白项均为保留(reserved),不得使用。
- 不要依赖任何**未定义(undefined)或保留(reserved)**位置的行为。
A.4 一字节与两字节操作码的操作码扩展
(OPCODE EXTENSIONS FOR ONE-BYTE AND TWO-BYTE OPCODES)
某些 一字节(1-byte) 和 两字节(2-byte) 操作码,
会将 ModR/M 字节中的第 3–5 位
(即 图 A-1 中的 nnn 字段)
用作 操作码的扩展(opcode extension)。

带有**操作码扩展(opcode extension)**的操作码,
在 表 A-6 中进行了标注,并按照 组号(group number) 进行组织。
-
组号(从 1 到 16,位于表的第二列)
用于在表中确定具体的查找入口(table entry point)。 -
每条指令中 r/m 字段的编码方式,
可以通过表中 第三列 给出的信息来确定。
A.4.1 使用操作码扩展的查表示例
(Opcode Look-up Examples Using Opcode Extensions)
下面通过示例说明如何使用操作码扩展(opcode extension)进行查表。
示例 A-4:解释一条 ADD 指令
(Interpreting an ADD Instruction)
一条 1 字节操作码为 80H 的 ADD 指令,
属于 Group 1 指令:
-
表 A-6 指出:
该指令在 ModR/M 字节中编码的操作码扩展字段
(即 reg/opcode 字段,nnn 位)为000B。 -
r/m 字段可以被编码为:
- 寄存器操作数(
mod = 11B),或 - 内存操作数,使用指定的寻址方式
(例如:mod = 00B、01B、10B)。
- 寄存器操作数(
示例 A-5:查找 0F 01 C3
(Looking Up 0F01C3H)
使用 表 A-2、表 A-3 和表 A-6
对操作码 0F 01 C3 进行查表,以确定其对应的指令 VMRESUME:
-
0F
表明该指令属于 两字节操作码映射表。 -
01- 在 表 A-3 中,对应 第 0 行、第 1 列。
- 该表项表明此操作码属于 表 A-6 中的 Group 7。
-
C3
这是 ModR/M 字节。C3的高两位为11B,
表示应查看 表 A-6 中 Group 7 的第二行。
-
Op/Reg 位(位 [5:3]) =
000B
表示在 Group 7 中查找000列。 -
R/M 位(位 [2:0]) =
011B
最终确定该操作码对应的指令为:VMRESUME
A.4.2 操作码扩展表
(Opcode Extension Tables)
操作码扩展表请参见下文中的 表 A-6。
Table A-6


注释(NOTES)
- 所有操作码映射表中的空白项均为保留项(reserved),不得使用。
- 不要依赖任何**未定义(undefined)或保留(reserved)**位置的行为。
更多推荐

所有评论(0)