intel白皮书卷2 第二章(AI翻译)

第 2 章

指令格式

(CHAPTER 2 --- INSTRUCTION FORMAT)

本章描述 所有 Intel 64 与 IA-32 处理器架构 中的指令格式

针对 保护模式(Protected Mode)实模式(Real Mode) 以及
虚拟 8086 模式(Virtual-8086 Mode) 下的指令格式,

将在 第 2.1 节中进行说明。

IA-32e 模式及其各个子模式 所引入的指令格式扩展与变化,

将在 第 2.2 节中进行说明。

2.1 保护模式、实模式与虚拟 8086 模式下的指令格式

(INSTRUCTION FORMAT FOR PROTECTED MODE, REAL MODE, AND VIRTUAL-8086 MODE)

Intel 64 与 IA-32 架构的指令编码,都是 图 2-1 所示指令格式的子集。

一条指令由以下部分组成(是否出现取决于具体指令):

  • 可选的指令前缀(Instruction Prefixes)(顺序不限)
  • 主操作码(Primary Opcode)(最多 3 个字节)
  • 寻址方式说明符(Addressing-Form Specifier) (如果需要),
    ModR/M 字节 构成,在某些情况下还包括
    SIB(Scale-Index-Base)字节
  • 偏移量(Displacement)(如果需要)
  • 立即数(Immediate)(如果需要)

2.1.1 指令前缀

(Instruction Prefixes)

指令前缀被划分为 四个组,每一组都有各自允许使用的前缀编码。

对于任意一条指令而言,每一组最多只需要使用一个前缀 (组 1、2、3、4 各最多一个)。

来自 第 1 组到第 4 组 的前缀,在编码时可以以任意顺序排列


■ 第 1 组(Group 1)

锁前缀与重复前缀(Lock and Repeat Prefixes):

  • LOCK 前缀

    使用 F0H 编码。

  • REPNE / REPNZ 前缀

    使用 F2H 编码。
    重复非零(Repeat-Not-Zero) 前缀仅适用于字符串指令输入/输出指令

    (F2H 也被某些指令用作强制前缀(mandatory prefix)。)

  • REP 或 REPE / REPZ 前缀

    使用 F3H 编码。
    重复(Repeat) 前缀仅适用于字符串指令输入/输出指令

    (F3H 也被某些指令用作强制前缀(mandatory prefix)。)


■ 第 2 组(Group 2)

段覆盖前缀(Segment Override Prefixes):
  • 2EH --- CS 段覆盖前缀(与任何分支指令一起使用是保留的)
  • 36H --- SS 段覆盖前缀(与任何分支指令一起使用是保留的)
  • 3EH --- DS 段覆盖前缀(与任何分支指令一起使用是保留的)
  • 26H --- ES 段覆盖前缀(与任何分支指令一起使用是保留的)
  • 64H --- FS 段覆盖前缀(与任何分支指令一起使用是保留的)
  • 65H --- GS 段覆盖前缀(与任何分支指令一起使用是保留的)
分支预测提示前缀(Branch Hints):
  • 2EH --- 分支不跳转(Branch Not Taken,仅用于 Jcc 指令)
  • 3EH --- 分支跳转(Branch Taken,仅用于 Jcc 指令)

■ 第 3 组(Group 3)

  • 操作数大小覆盖前缀(Operand-Size Override Prefix)
    使用 66H 编码。
    (66H 也被某些指令用作强制前缀。)

■ 第 4 组(Group 4)

  • 67H --- 地址大小覆盖前缀(Address-Size Override Prefix)

LOCK 前缀说明

LOCK 前缀(F0H)

用于在多处理器环境 中,强制某些操作对共享内存的独占访问

关于该前缀的详细说明,请参见
第 3 章《指令集参考(A--M)》 中的
"LOCK---Assert LOCK# Signal Prefix"


重复前缀说明(REP / REPNE)

重复前缀(F2H、F3H)

用于使指令对字符串中的每一个元素重复执行

这些前缀只能用于字符串指令和 I/O 指令,包括:

  • MOVS
  • CMPS
  • SCAS
  • LODS
  • STOS
  • INS
  • OUTS

将重复前缀或未定义的操作码用于其他 Intel 64 或 IA-32 指令是保留行为

此类用法可能导致不可预测的行为

某些指令会将 F2H 或 F3H 用作强制前缀

以表达不同的指令语义。

通常情况下,强制前缀应当放置在其他可选前缀之后

(这一规则的例外情况在 **2.2.1 节《REX 前缀》**中说明)。


分支预测提示前缀说明

分支预测提示前缀(2EH、3EH)

允许程序向处理器提示某个分支最可能执行的路径

这些前缀只能与条件分支指令(Jcc)一起使用

在其他指令中使用分支预测提示前缀,或使用未定义的操作码,

均属于保留行为 ,可能导致不可预测的行为


操作数大小覆盖前缀(66H)

操作数大小覆盖前缀允许程序在 16 位32 位操作数大小之间切换。

  • 默认操作数大小由当前运行模式决定
  • 使用该前缀将选择非默认的操作数大小

某些 SSE2 / SSE3 / SSSE3 / SSE4 指令

以及使用 三字节主操作码序列 的指令,

会将 66H 用作强制前缀以表示不同的功能。

通常情况下,强制前缀应当放在其他可选前缀之后

(REX 前缀的特殊情况见 2.2.1 节)。

66H 用于其他未定义场景是保留行为

此类用法可能导致不可预测的行为


地址大小覆盖前缀(67H)

地址大小覆盖前缀(67H)

允许程序在 16 位32 位地址大小之间切换。

  • 默认地址大小由当前运行模式决定
  • 使用该前缀将选择非默认的地址大小

当指令的操作数不位于内存中 时,

使用该前缀或其他未定义操作码属于保留行为

可能导致不可预测的行为

2.1.2 操作码

(Opcodes)

主操作码(Primary Opcode) 的长度可以是 1 字节、2 字节或 3 字节

在某些情况下,还会在 ModR/M 字节 中编码一个额外的 3 位操作码字段

此外,主操作码内部还可能划分出更小的字段,用于表示:

  • 操作方向
  • 偏移量大小
  • 寄存器编码
  • 条件码
  • 符号扩展方式

具体由哪些编码字段参与操作码的定义,

取决于该指令所属的操作类别。


双字节操作码格式

(Two-Byte Opcode Formats)

用于 通用指令SIMD 指令的双字节操作码格式包括以下两种形式之一:

  • 转义操作码字节 0FH 作为主操作码,后跟 一个操作码字节;或
  • 强制前缀(66H、F2H 或 F3H) 开头,
    后跟 转义操作码字节 0FH ,再跟 一个操作码字节
    (与上一种形式的操作码结构相同)
示例

指令 CVTDQ2PD 的操作码字节序列如下:

cpp 复制代码
F3 0F E6

其中:

  • 第一个字节 F3H强制前缀
    (在此情形下,它不被视为重复前缀

三字节操作码格式

(Three-Byte Opcode Formats)

用于 通用指令SIMD 指令的三字节操作码格式包括以下两种形式之一:

  • 转义操作码字节 0FH 作为主操作码,
    后跟 两个额外的操作码字节;或
  • 强制前缀(66H、F2H 或 F3H) 开头,
    后跟 转义操作码字节 0FH ,再跟 两个额外的操作码字节
    (与上一种形式的操作码结构相同)
示例

针对 XMM 寄存器PHADDW 指令,其操作码字节序列如下:

cpp 复制代码
66 0F 38 01

其中:

  • 第一个字节 66H强制前缀

操作码表达式的定义位置

有效的操作码表达式定义在以下附录中:

  • 附录 A
  • 附录 B

2.1.3 ModR/M 与 SIB 字节

(ModR/M and SIB Bytes)

许多访问内存操作数 的指令,在主操作码之后都会跟随一个
寻址方式说明符字节(addressing-form specifier)

该字节称为 ModR/M 字节

ModR/M 字节包含三个信息字段:

  • mod 字段

    mod 字段与 r/m 字段组合后,可以形成 32 种不同的取值

    其中包括 8 种寄存器形式24 种内存寻址方式

  • reg/opcode 字段

    reg/opcode 字段用于指定:

    • 一个寄存器编号,或
    • 额外的 3 位操作码信息

    reg/opcode 字段的具体用途由 主操作码决定。

  • r/m 字段

    r/m 字段可以:

    • 直接指定一个寄存器作为操作数,或
    • 与 mod 字段组合,用于编码一种内存寻址方式

    在某些指令中,mod 字段与 r/m 字段的特定组合

    还会被用来表示操作码相关的信息


SIB 字节(Scale-Index-Base Byte)

ModR/M 字节的某些编码形式需要一个第二个寻址字节

SIB(Scale-Index-Base)字节

32 位地址模式下,以下寻址形式必须使用 SIB 字节:

  • 基址 + 索引(base + index)
  • 比例 × 索引(scale × index)

SIB 字节包含以下字段:

  • scale 字段

    用于指定比例因子(scale factor)

  • index 字段

    用于指定索引寄存器的寄存器编号

  • base 字段

    用于指定基址寄存器的寄存器编号


编码参考

有关 ModR/M 字节SIB 字节 的具体编码方式,

请参见 第 2.1.5 节

2.1.4 偏移量与立即数字节

(Displacement and Immediate Bytes)

某些寻址形式会在 ModR/M 字节 之后

(如果存在 SIB 字节 ,则在 SIB 字节之后)

紧跟一个 偏移量(displacement)

如果指令需要偏移量,该偏移量的长度可以是:

  • 1 字节
  • 2 字节
  • 4 字节

如果一条指令指定了 立即数操作数(immediate operand)

该操作数始终位于所有偏移量字节之后

立即数操作数的长度可以是:

  • 1 字节
  • 2 字节
  • 4 字节

2.1.5 ModR/M 与 SIB 字节的寻址方式编码

(Addressing-Mode Encoding of ModR/M and SIB Bytes)

ModR/M 字节与 SIB 字节的取值及其对应的寻址形式,

列于 表 2-1 至 表 2-3 中:

  • 表 2-1 :由 ModR/M 字节指定的 16 位寻址形式
  • 表 2-2 :由 ModR/M 字节指定的 32 位寻址形式
  • 表 2-3 :由 SIB 字节指定的 32 位寻址形式

ModR/M 字节的 reg/opcode 字段 表示扩展操作码 的情况下,

其有效编码列于 附录 B 中。


ModR/M 表中有效地址的含义

表 2-1表 2-2 中,
"Effective Address(有效地址)" 一列列出了

通过 ModR/M 字节中的 Mod 与 R/M 字段

可分配给指令第一个操作数32 种有效地址形式

  • 24 种 形式用于指定内存位置
  • 8 种 形式(Mod = 11B
    用于指定:
    • 通用寄存器
    • MMX 技术寄存器
    • XMM 寄存器

Mod 与 R/M 字段的编码方式

表 2-1表 2-2 中,
Mod 列与 R/M 列给出了

为获得"Effective Address"列中所列地址形式而需要的
Mod 字段与 R/M 字段的二进制编码值

示例说明

Mod = 11B,R/M = 000B 所在的表项为例:

该表项对应的操作数可以是:

  • 通用寄存器 EAX、AX 或 AL
  • MMX 技术寄存器 MM0
  • XMM 寄存器 XMM0

具体使用哪一种寄存器,

操作码字节操作数大小属性共同决定。


Reg/Opcode 字段作为第二操作数

再看表中的第七行 (标记为 "REG ="):

该行说明了当 3 位 Reg/Opcode 字段

用于指定第二个操作数的位置时的用法。

  • 第二个操作数必须是:
    • 通用寄存器,或
    • MMX 技术寄存器,或
    • XMM 寄存器
  • 表中 第 1 至第 5 行
    列出了 Reg/Opcode 字段各取值所对应的寄存器

同样,实际使用的寄存器类型

操作码字节操作数大小属性决定。


Reg/Opcode 字段作为操作码扩展

如果指令不需要第二个操作数

Reg/Opcode 字段 可以被用作操作码扩展(opcode extension)

这种用法在表中由第六行 表示(标记为 "/digit (Opcode)")。

需要注意的是:

  • 第六行中的取值以十进制形式表示

ModR/M 字节 256 种取值的表示方式

表 2-1表 2-2 的主体部分

(位于 "Value of ModR/M Byte (in Hexadecimal)" 标题之下)

包含一个 32 × 8 的矩阵

以十六进制形式展示了 ModR/M 字节全部 256 种可能取值

在该矩阵中:

  • 表格的 指定了 第 3、4、5 位
  • 表格的 指定了:
    • 第 0、1、2 位
    • 以及 第 6、7 位

下图展示了如何对表中的某一个取值进行解释。

注释(NOTES)
  1. 当有效地址中包含 BP 作为索引寄存器 时,

    默认使用的段寄存器是 SS

    对于其他有效地址,默认使用的段寄存器是 DS

  2. disp16 表示一个 16 位偏移量

    该偏移量紧随 ModR/M 字节 之后,

    并被加到索引值中。

  3. disp8 表示一个 8 位偏移量

    该偏移量紧随 ModR/M 字节 之后,

    会先进行符号扩展(sign-extended)

    再被加到索引值中。

注释(NOTES)
  1. [--][--] 这种记号表示:

    ModR/M 字节 之后还会紧跟一个 SIB 字节

  2. disp32 表示一个 32 位偏移量

    该偏移量紧随 ModR/M 字节 之后

    (如果存在 SIB 字节,则位于 SIB 字节之后 ),

    并被加到索引值中。

  3. disp8 表示一个 8 位偏移量

    该偏移量紧随 ModR/M 字节 之后

    (如果存在 SIB 字节,则位于 SIB 字节之后 ),

    在参与计算前会进行符号扩展(sign-extended)

    然后再加到索引值中。


表 2-3 说明(SIB 字节编码)

表 2-3 的组织方式用于展示 SIB 字节全部 256 种可能取值

(以十六进制形式表示)。

  • 表格顶部 列出了作为 基址(base) 使用的通用寄存器,

    以及它们在 SIB 字节的 base 字段中对应的取值。

  • 表格主体中的各行用于表示:

    • 索引寄存器 (由 SIB 字节的第 3、4、5 位指定)
    • 比例因子(scaling factor)
      (由 SIB 字节的第 6、7 位确定)

注释(NOTES)

  1. [*] 这种记号的含义如下:

    • MOD = 00B 时,[*] 表示 无基址寄存器 ,仅使用一个 32 位偏移量(disp32)
    • 否则,[*] 表示 disp8 或 disp32 + [EBP]

    由此可得到以下寻址方式:

    MOD 位 有效地址(Effective Address)
    00 [scaled index] + disp32
    01 [scaled index] + disp8 + [EBP]
    10 [scaled index] + disp32 + [EBP]


2.2 IA-32e 模式

(IA-32e Mode)

IA-32e 模式包含两个子模式,分别是:

  • 兼容模式(Compatibility Mode)

    允许 64 位操作系统 在不修改的情况下,运行大多数传统的保护模式软件

  • 64 位模式(64-Bit Mode)

    允许 64 位操作系统 运行为访问 64 位地址空间而编写的应用程序。

2.2.1 REX 前缀

(REX Prefixes)

REX 前缀 是在 64 位模式 下使用的一类指令前缀字节,其作用包括:

  • 指定 通用寄存器(GPR)SSE 寄存器
  • 指定 64 位操作数大小
  • 指定 扩展的控制寄存器

并非所有指令在 64 位模式下都需要使用 REX 前缀。

只有在以下情况下,才必须使用 REX 前缀:

  • 指令引用了扩展寄存器,或
  • 指令使用了 64 位操作数

如果在指令中使用了 没有语义意义的 REX 前缀

该前缀会被忽略


REX 前缀的使用规则

  • 每条指令最多只能包含一个 REX 前缀
  • 如果使用 REX 前缀,
    REX 前缀字节必须紧邻操作码字节之前
    或者紧邻 转义操作码字节(0FH) 之前。

当 REX 前缀与包含强制前缀的指令 一起使用时,
强制前缀必须位于 REX 前缀之前

以保证 REX 前缀能够紧邻操作码字节或转义字节

示例说明

以带有 REX 前缀的 CVTDQ2PD 指令为例:

cpp 复制代码
F3 REX 0F E6

在该指令中:

  • F3 为强制前缀
  • REX 位于 F3 与 0F E6 之间

其他位置放置 REX 前缀的情况都会被忽略


指令长度限制

即使使用了 REX 前缀,
指令长度仍然受 15 字节上限的限制

有关 REX 前缀位置与格式的示意,

请参见 图 2-3

2.2.1.1 编码方式

(Encoding)

在 Intel 64 与 IA-32 的指令格式中,根据具体的编码形式,

最多可以通过 3 位字段 来指定 三个寄存器,具体如下:

  • 使用 ModR/M 字节的指令

    通过 ModR/M 字节中的 reg 字段与 r/m 字段来指定寄存器。

  • 使用 ModR/M 与 SIB 字节的指令

    通过 ModR/M 字节中的 reg 字段

    以及 SIB(scale, index, base)字节中的 base 与 index 字段来指定寄存器。

  • 不使用 ModR/M 字节的指令

    通过 操作码中的 reg 字段来指定寄存器。


64 位模式 下,上述指令编码格式本身并不会发生变化

用于在 64 位上下文 中定义这些字段所需的额外位,

REX 前缀的引入来提供。

2.2.1.2 关于 REX 前缀字段的进一步说明

(More on REX Prefix Fields)

REX 前缀是一组 16 个操作码

它们在操作码映射表中占据同一行,对应 40H 到 4FH 这一区间。

IA-32 操作模式 以及 兼容模式(Compatibility Mode)下,
这些操作码表示的是
有效指令
(INC 或 DEC)。

而在 64 位模式 下,

同样的操作码被解释为 REX 指令前缀

不再被视为独立的指令。


单字节 INC / DEC 指令在 64 位模式下的情况

单字节操作码形式的 INC / DEC 指令

64 位模式下不可用。

不过,INC / DEC 的功能仍然可以通过

这些指令的 ModR/M 编码形式来实现:

  • FF /0 → INC
  • FF /1 → DEC

REX 前缀格式与示例

  • 有关 REX 前缀格式的汇总说明 ,请参见 表 2-4
  • 图 2-4 到 图 2-7 展示了 REX 前缀字段在实际指令中的使用示例。

某些 REX 前缀字段组合是无效的

在这种情况下,该 REX 前缀会被忽略


REX 前缀字段的补充说明

  • REX.W 位

    REX.W 可用于确定操作数大小

    并不能单独决定最终的操作数位宽

    66H 操作数大小覆盖前缀 类似,
    64 位操作数大小覆盖字节级操作没有影响。

  • REX.W 与 66H 的关系(非字节操作)

    对于非字节操作

    • 如果同时使用 66H 前缀 并且 REX.W = 1
      66H 前缀会被忽略
    • 如果同时使用 66H 前缀REX 前缀 ,且 REX.W = 0
      则操作数大小为 16 位
  • REX.R 位

    REX.R 用于扩展 ModR/M 字节中的 reg 字段

    当该字段用于编码以下寄存器时有效:

    • 通用寄存器(GPR)
    • SSE 寄存器
    • 控制寄存器
    • 调试寄存器

    当 ModR/M 字节用于指定其他类型的寄存器

    或用于定义扩展操作码 时,
    REX.R 位会被忽略

  • REX.X 位

    REX.X 用于扩展 SIB 字节中的 index 字段

  • REX.B 位

    REX.B 的作用包括以下几种情况之一:

    • 扩展 ModR/M 字节中的 r/m 字段所指定的基址寄存器;或
    • 扩展 SIB 字节中的 base 字段;或
    • 扩展 操作码中的 reg 字段,用于访问通用寄存器(GPR)。

在 IA-32 架构中,字节寄存器 (AH、AL、BH、BL、CH、CL、DH 和 DL)

被编码为编号 0 到 7 的寄存器,

具体位置可以位于:

  • ModR/M 字节的 reg 字段
  • ModR/M 字节的 r/m 字段
  • 操作码中的 reg 字段

REX 前缀 为字节寄存器提供了额外的寻址能力

使得 通用寄存器(GPR)中最低有效字节

也可以用于 字节级操作


特殊寄存器编码情况

在某些情况下,
ModR/M 字节与 SIB 字节中的字段组合

对寄存器编码具有特殊含义

对于其中的一些组合,

即使存在 REX 前缀

由 REX 前缀扩展的字段也不会被解码

这些情况在 表 2-5 中进行了详细说明。

注释(NOTES)

  • 无需关心 REX.B 的取值

2.2.1.3 偏移量

(Displacement)

64 位模式 下,内存寻址仍然使用现有的 32 位 ModR/M 与 SIB 编码形式
ModR/M 与 SIB 所使用的偏移量大小不会发生变化,仍然为:

  • 8 位偏移量(disp8),或
  • 32 位偏移量(disp32)

这些偏移量在 64 位模式下会被**符号扩展(sign-extended)**为 64 位后参与地址计算。

2.2.1.4 直接内存偏移形式的 MOV 指令

(Direct Memory-Offset MOVs)

64 位模式 下,
MOV 指令的直接内存偏移形式 被扩展为可以指定一个
64 位的立即数绝对地址

该地址被称为 moffset(memory offset)

指定该 64 位内存偏移地址 时,不需要使用任何前缀

对于这些 MOV 指令,
内存偏移量的大小遵循地址大小的默认值

在 64 位模式下为 64 位

有关这些指令的编码形式,请参见 表 2-6

2.2.1.5 立即数

(Immediates)

64 位模式 下,立即数操作数 的常见大小仍然是 32 位

当指令的操作数大小为 64 位 时,处理器会在使用之前,

将所有立即数**符号扩展(sign-extended)**为 64 位

64 位立即数操作数 的支持,是通过扩展现有的移动指令语义 来实现的,

具体体现在 MOV reg, imm16/32 这类指令上。

这些指令(操作码 B8H--BFH

会将 16 位或 32 位的立即数数据 (取决于有效的操作数大小)

移动到一个 **通用寄存器(GPR)**中。

有效操作数大小为 64 位 时,

这些指令可以用于将一个立即数加载到 GPR 中

此时,需要使用 REX 前缀

以将默认的 32 位操作数大小 覆盖为 64 位操作数大小


示例
cpp 复制代码
48 B8 88 77 66 55 44 33 22 11

对应的汇编指令为:

cpp 复制代码
MOV RAX, 1122334455667788H

2.2.1.6 RIP 相对寻址

(RIP-Relative Addressing)

64 位模式 下,引入了一种新的寻址形式------
RIP 相对寻址(relative instruction-pointer addressing)

在该寻址方式中,有效地址通过以下方式形成:

有效地址 = 下一条指令的 64 位 RIP + 偏移量


IA-32 架构 以及 兼容模式 下,
相对于指令指针的寻址 仅适用于控制转移指令

而在 64 位模式 下,
使用 ModR/M 寻址方式的指令 也可以使用 RIP 相对寻址

如果不使用 RIP 相对寻址,

所有基于 ModR/M 的指令寻址方式都会将内存地址视为相对于 0 的地址


RIP 相对寻址的偏移量范围

RIP 相对寻址允许特定的 ModR/M 编码形式

使用一个 有符号的 32 位偏移量(disp32)

相对于 64 位 RIP 来访问内存。

这使得可访问的地址范围为:

  • RIP ± 2GB

编码形式说明

表 2-7 列出了 RIP 相对寻址 所使用的
ModR/M 与 SIB 编码形式

在当前的 ModR/M 与 SIB 编码中,

已经存在一些 32 位偏移量寻址的冗余形式

  • 存在 一种 ModR/M 编码形式
  • 以及 若干种 SIB 编码形式

RIP 相对寻址正是通过使用其中的一种冗余编码形式来实现的。


Disp32 编码在 64 位模式下的重新定义

64 位模式 下,
ModR/M 的 Disp32(32 位偏移量)编码被重新定义为:

cpp 复制代码
RIP + Disp32

而不再表示仅由偏移量构成的绝对地址

有关该重新定义的具体细节,请参见 表 2-7

RIP 相对寻址所使用的 ModR/M 编码
并不依赖任何前缀的使用

具体而言,用于选择 RIP 相对寻址r/m 位字段编码 101B
不会受到 REX 前缀的影响

例如:

  • REX.B = 1r/m = 101B(即试图选择 R13)
  • 并且 mod = 00B

此时,编码结果仍然表示 RIP 相对寻址

而不是以 R13 作为基址寄存器。


关于 R13 与 r/m = 101B 的特殊情况

REX.B 与 ModR/M 组合后的 4 位 r/m 字段
不会被完整解码

因此,

若软件希望在无偏移量 的情况下访问 R13

必须将其编码为:

cpp 复制代码
R13 + 0

也就是说,需要使用一个 值为 0 的 1 字节偏移量(disp8 = 0)

而不能使用 mod = 00B, r/m = 101B 的编码形式。


RIP 相对寻址与地址大小前缀的关系

RIP 相对寻址的启用条件是:

  • 64 位模式

不是

  • 64 位地址大小

因此,使用地址大小覆盖前缀
不会禁用 RIP 相对寻址

地址大小前缀的作用仅是:

  • 将计算得到的 有效地址
    截断为 32 位
  • 然后再对其进行 零扩展(zero-extend),扩展为 64 位

2.2.1.7 默认的 64 位操作数大小

(Default 64-Bit Operand Size)

64 位模式 下,有两类指令的默认操作数大小即为 64 位

因此不需要使用 REX 前缀来指定 64 位操作数大小。这两类指令是:

  • 近跳转指令(Near branches)
  • 所有隐式引用 RSP 的指令(不包括远跳转指令)

2.2.2 控制寄存器与调试寄存器的附加编码

(Additional Encodings for Control and Debug Registers)

64 位模式 下,

控制寄存器(Control Registers)调试寄存器(Debug Registers)

提供了更多的编码方式。

ModR/M 字节中的 reg 字段 用于编码控制寄存器或调试寄存器时,
REX.R 位 用于对该字段进行扩展(参见 表 2-4)。

这些扩展编码使处理器能够访问:

  • CR8--CR15
  • DR8--DR15

CR8 的引入

64 位模式 下,引入了一个新的控制寄存器 CR8

CR8 被定义为 任务优先级寄存器(Task Priority Register,TPR)


未实现寄存器的访问行为

IA-32e 模式的最初实现中

  • CR9--CR15
  • DR8--DR15

未被实现

任何尝试访问这些未实现寄存器 的行为,

都会导致处理器产生一个 无效操作码异常(#UD)

相关推荐
命里有定数26 分钟前
保姆级教程:在 Windows (WSL2) 下本地部署 Qwen3-ASR
windows
lucky67074 小时前
Windows 上彻底卸载 Node.js
windows·node.js
编程小白20264 小时前
从 C++ 基础到效率翻倍:Qt 开发环境搭建与Windows 神级快捷键指南
开发语言·c++·windows·qt·学习
凯子坚持 c6 小时前
CANN 性能剖析实战:从原始事件到交互式火焰图
windows·microsoft
开开心心就好6 小时前
发票合并打印工具,多页布局设置实时预览
linux·运维·服务器·windows·pdf·harmonyos·1024程序员节
獨枭7 小时前
PyCharm 跑通 SAM 全流程实战
windows
仙剑魔尊重楼7 小时前
音乐制作电子软件FL Studio2025.2.4.5242中文版新功能介绍
windows·音频·录屏·音乐·fl studio
PHP小志8 小时前
Windows 服务器怎么修改密码和用户名?账户被系统锁定如何解锁
windows
专注VB编程开发20年9 小时前
vb.net datatable新增数据时改用数组缓存
java·linux·windows
仙剑魔尊重楼9 小时前
专业音乐制作软件fl Studio 2025.2.4.5242中文版新功能
windows·音乐·fl studio