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)

相关推荐
爱编码的傅同学2 小时前
【线程同步】信号量与环形队列的生产消费模型
linux·windows·ubuntu·centos
专注VB编程开发20年3 小时前
如何强制ANY CPU的.net程序按32位或64位模式运行?
windows·.net
yaoxin5211235 小时前
303. Java Stream API - 查找元素
java·windows·python
z.q.xiao7 小时前
【镜像模式】WSL如何访问windows内网服务
linux·网络·windows·gitlab·wsl·dns
gf13211117 小时前
python_生成RPA运行数据报告
windows·python·rpa
FL16238631298 小时前
Windows上GPU版本的Paddle Inference3.2.1安装和使用教程
windows·paddle
嘴贱欠吻!20 小时前
Kuikly搭建OpenHarmony教程01:源码构建与运行(Windows)
windows
2601_949480061 天前
Flutter for OpenHarmony 音乐播放器App实战 - 主题设置实现
windows·flutter
石像鬼₧魂石1 天前
内网渗透学习框架:五维金字塔
windows·学习