x64指令编码和ModRM字节

rwa*_*ace 7 64-bit x86 assembly x86-64 instruction-set

编码

call qword ptr [rax]
call qword ptr [rcx]
Run Code Online (Sandbox Code Playgroud)

FF 10
FF 11
Run Code Online (Sandbox Code Playgroud)

我可以看到最后一个数字(0/1)的来源(寄存器号),但我想弄清楚第二个数字(1)的来源.根据AMD64架构程序员手册第3卷:通用和系统指令第56页,

"/ digit - 表示ModRM字节仅指定一个寄存器或存储器(r/m)操作数.该数字由ModRM寄存器字段指定,用作指令操作码扩展.有效数字值的范围为0到7. "

等效的英特尔文档说明了类似的内容,并call通过寄存器指定编码为

FF /2
Run Code Online (Sandbox Code Playgroud)

并且...我不知道这意味着什么,或者规范中的2如何连接到最终结果中的高1位数.在任何地方都有不同措辞的解释吗?

Lan*_*ard 8

英特尔文档第 2A 卷的表 2-2 中的平均值查找(表和卷中的 2 与那里/2没有关系)。/2在左上角的表格中有/digit. 因此,转到右侧的列并找到/2. 我们稍后会回来讨论这一点。

现在,如果您查看call指令定义,您将看到Op/En“操作数编码”。

Op/En       Operand 1       Operand 2       Operand 3       Operand 4
D           Offset          NA              NA              NA
M           ModRM:r/m (r)   NA              NA              NA
Run Code Online (Sandbox Code Playgroud)

还要注意call第一个表中的签名,例如这个,它是 64 位的,对应于用法rax

Opcode    Instruction   Op/En
FF /2     CALL r/m64    M
Run Code Online (Sandbox Code Playgroud)

M告诉我们在下面的“操作数编码”(Op/En)表中查找M,即:

Op/En       Operand 1       Operand 2     Operand 3       Operand 4
M           ModRM:r/m (r)   NA            NA              NA
Run Code Online (Sandbox Code Playgroud)

所以操作数 1 是ModRM:r/m (r)。这(r)意味着操作数被读取(而不是写入)。ModRM:r/m 表示操作数有一个 ModRM 字节,带有 r/m 值。inrr/m意思是“寄存器”,而 the 的m意思是“内存”。

回到/2表 2-2 中的列,我们有010,就在 的行上REG。这是指 ModRM 中间的“reg”段。

据此我们有:

mod     description (relevant to us)
00      register indirect addressing mode
01      one-byte signed displacement follows addressing mode byte(s)
10      four-byte signed displacement follows addressing mode byte(s)
11      register addressing mode
Run Code Online (Sandbox Code Playgroud)

由于我们使用的是[rax],即寄存器间接寻址模式,所以00

所以我们有了 mod 和 reg,现在我们需要 r/m 来完成 ModRM 字节。

来自网络上其他地方: r/m 字段对使用哪个寄存器进行编码。如果我们返回表 2-2 和该列,并将其与左侧的/2Mod 框匹配,并且我们使用该行(与您的 中使用的相同),我们最终会得到。同样,如果我们遵循该行(与您的相同),我们会得到。这给了我们:00EAXRAXcall [rax]10ECXRCXcall [rcx]11

FF 10       call [rax]
FF 11       call [rcx]
Run Code Online (Sandbox Code Playgroud)

请注意,该表还显示了 r/m 值:000forrax001for rcx。这给了我们最终的 ModRM 字节。

ModRM         for        hex
00.010.000    rax        10
00.010.001    rcx        11
Run Code Online (Sandbox Code Playgroud)

还要注意,如果您这样做call [eax],它的前缀是67十六进制:

67 FF 01
Run Code Online (Sandbox Code Playgroud)

这对应于“地址大小覆盖前缀”。


nrz*_*nrz 7

我想您要查看英特尔®64和IA-32架构开发人员手册中的表2-2 :组合卷,第2卷:指令参考集,第2章:指令格式,2.1.5 ModR/M的寻址模式编码和SIB字节:

Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte

r8(/r)                       AL   CL   DL   BL   AH   CH   DH   BH
r16(/r)                      AX   CX   DX   BX   SP   BP   SI   DI
r32(/r)                      EAX  ECX  EDX  EBX  ESP  EBP  ESI  EDI
mm(/r)                       MM0  MM1  MM2  MM3  MM4  MM5  MM6  MM7
xmm(/r)                      XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7
(In decimal) /digit (Opcode) 0    1    2    3    4    5    6    7
(In binary) REG =            000  001  010  011  100  101  110  111
Effective Address Mod R/M    Value of ModR/M Byte (in Hexadecimal)
[EAX]              00 000    00   08   10   18   20   28   30   38
[ECX]                 001    01   09   11   19   21   29   31   39
[EDX]                 010    02   0A   12   1A   22   2A   32   3A
[EBX]                 011    03   0B   13   1B   23   2B   33   3B
[--][--] *1           100    04   0C   14   1C   24   2C   34   3C
disp32 *2             101    05   0D   15   1D   25   2D   35   3D
[ESI]                 110    06   0E   16   1E   26   2E   36   3E
[EDI]                 111    07   0F   17   1F   27   2F   37   3F
[EAX]+disp8 *3     01 000    40   48   50   58   60   68   70   78
[ECX]+disp8           001    41   49   51   59   61   69   71   79
[EDX]+disp8           010    42   4A   52   5A   62   6A   72   7A
[EBX]+disp8           011    43   4B   53   5B   63   6B   73   7B
[--][--]+disp8        100    44   4C   54   5C   64   6C   74   7C
[EBP]+disp8           101    45   4D   55   5D   65   6D   75   7D
[ESI]+disp8           110    46   4E   56   5E   66   6E   76   7E
[EDI]+disp8           111    47   4F   57   5F   67   6F   77   7F
[EAX]+disp32       10 000    80   88   90   98   A0   A8   B0   B8
[ECX]+disp32          001    81   89   91   99   A1   A9   B1   B9
[EDX]+disp32          010    82   8A   92   9A   A2   AA   B2   BA
[EBX]+disp32          011    83   8B   93   9B   A3   AB   B3   BB
[--][--]+disp32       100    84   8C   94   9C   A4   AC   B4   BC
[EBP]+disp32          101    85   8D   95   9D   A5   AD   B5   BD
[ESI]+disp32          110    86   8E   96   9E   A6   AE   B6   BE
[EDI]+disp32          111    87   8F   97   9F   A7   AF   B7   BF
EAX/AX/AL/MM0/XMM0 11 000    C0   C8   D0   D8   E0   E8   F0   F8
ECX/CX/CL/MM/XMM1     001    C1   C9   D1   D9   E1   E9   F1   F9
EDX/DX/DL/MM2/XMM2    010    C2   CA   D2   DA   E2   EA   F2   FA
EBX/BX/BL/MM3/XMM3    011    C3   CB   D3   DB   E3   EB   F3   FB
ESP/SP/AH/MM4/XMM4    100    C4   CC   D4   DC   E4   EC   F4   FC
EBP/BP/CH/MM5/XMM5    101    C5   CD   D5   DD   E5   ED   F5   FD
ESI/SI/DH/MM6/XMM6    110    C6   CE   D6   DE   E6   EE   F6   FE
EDI/DI/BH/MM7/XMM7    111    C7   CF   D7   DF   E7   EF   F7   FF
NOTES:
1. The [--][--] nomenclature means a SIB follows the ModR/M byte.
2. The disp32 nomenclature denotes a 32-bit displacement that follows the ModR/M byte (or the SIB
byte if one is present) and that is added to the index.
3. The disp8 nomenclature denotes an 8-bit displacement that follows the ModR/M byte (or the SIB
byte if one is present) and that is sign-extended and added to the index.


Ale*_*nze 7

ModR/M字节有3个字段:

bit 7 & bit 6 = mod
bit 5 through bit 3 = reg = /digit
bit 2 through bit 0 = r/m
Run Code Online (Sandbox Code Playgroud)

这在Figure 2-1. Intel 64 and IA-32 Architectures Instruction FormatVol.中有描述.2A of Intel® 64 and IA-32 Architectures Software Developer’s Manual.

所以,那里:

  0x10= 00.010.000(mod = 0 reg/digit=2,, r/m=0)

  0x11= 00.010.001(mod = 0 reg/digit=2,, r/m=1).