3

我正在使用最新的官方“英特尔® 64 和 IA-32 架构软件开发人员手册组合卷:1、2A、2B、2C、2D、3A、3B、3C、3D 和 4 ”作为参考来了解机器级别x86-64 ISA 的编码。

第 2 卷第 2.1.3 节中提供的 ModR/M 和 SIB 字节文档给出了引用 8 位、16 位和 32 位寄存器的准确编码(表 2-1、2-2 和 2 -3)

但是,我找不到一个类似的表来指定 REX 前缀中的 REX.X、REX.B、REX.R 字节如何与 ModR/M 结合来指定扩展寄存器。我专门为每个扩展寄存器寻找显式二进制编码。据我所知,手册中有关 REX 前缀的文档仅指定使用 REX 中的相应位在 MSB 中将 reg、r/m 字段扩展 1 位,但实际上并未给出显式映射位组合。

英特尔文档是否在 SDM 的任何位置明确说明了这些映射?还是只是假设 R8-R15 将遵循明显/自然的映射策略,其中 REX.B/X/R 设置为 1 并且 R8 编码为 000,R9 为 001 ... R15 为 111 ?

4

1 回答 1

3

是的,正如您发现的那样,它遵循简单的二进制编号,使用 REX 位作为前导位,ModRM 位作为低 3 位来编码寄存器编号。8 = 1000 二进制,这就是 R8 的编码。

https://wiki.osdev.org/X86-64_Instruction_Encoding#Encoding解释得很好,而且https://wiki.osdev.org/X86-64_Instruction_Encoding#Registers甚至还有一张桌子。


我搜索了 Intel 的 vol.2 PDF r14(这对任何东西都不是“特殊”的,并且可能只会出现在表格中)。vol.2中有一些表格,但没有一张用于简单 ModRM 本身的表格。(合并后的 PDF 太大而无法使用)。

Vol.2清楚地描述了 REX 字段如何与 ModRM 字段结合以生成 4 位寄存器编号。(例如图 2-4 显示了 REX.B 和 ModRM.rm 的连接,以及 REX.R 和 ModRM.r 的连接)。我没有检查 vol.1 - 如果可以在那里找到一些关于寄存器名称(由汇编程序使用)匹配二进制寄存器号的语句,我不会感到惊讶。名称仅对汇编程序有意义,而不是机器代码,并且在 vol.2 中有明确记录。


但是,该信息第 2 卷中:

它确实有表 3-1。与 +rb、+rw、+rd、+ro 相关的寄存器代码(续)用于没有 ModRM 的指令,其中操作码字节的低 3 位是寄存器编号的低 3 位。(就像 push/pop r64 的短编码一样)。

注册 雷克斯 注册字段
R13B 是的 5
R14B 是的 6

依此类推,每个寄存器都有行,R14W、R14D、R14 的 word、dword 和 qword 大小还有 3 组列。因此,如果您对二进制数映射到寄存器名称这一事实有疑问,该表说明了这一点。(假设寄存器号码在这里的工作方式与在其他情况下不同,那就太疯狂了。)

还有单字节操作码的操作码映射,其中push rSI/r14共享一个条目 (0x58),对于 xchg-with-(e)ax、mov-immediate 到 byte-reg、pop、mov-immediate 到 word/dword/qword- 相同reg 和 bswap 在 2 字节操作码映射中。同样,这些注册号码的工作方式与其他地方的注册号码不同,这将是疯狂的。

有一个完整的表表 2-8。VEX.vvvv 用于注册名称映射,带有 xmm/ymm0..15 和 RAX/EAX .. R15/R15D。(VEX.vvvv 可以为 BMI 指令andn66

表 2-13。SIB 字节的 32 位 VSIB 寻址形式也是相关的,显示 ESI/R14D 等列。(在 64 位模式下,您通常不会使用 67 地址大小前缀vpgatherdd或其他任何东西,但您可以。没有单独的 64 位地址大小表。)该表没有明确提及VEX.B如何针对给定的位 2:0 值在两个寄存器之间进行选择,但这显然应该来自其他情况。

于 2021-08-19T21:07:03.290 回答