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