X86
x86指令格式 > ModR/M与SIB

许多指令的内存操作数需要使用ModR/M字节作为寻址模式说明符。其中的mod与r/m组合，共有32个值，表示8个寄存器与24种寻址模式。reg/opcode表示寄存器号或者额外的3位指令码，其具体含义依赖基本指令码。Mod与R/M的5位表示的第一操作数（源与目的操作数中寻址方式更复杂的那个操作数，指令码中的“方向位”direction bit(d)给出源或目的操作数哪个是第一操作数）的寻址方式如下：
| 寻址方式 | Mod | R/M |
| --- | --- | --- |
| [EAX] | 00 | 000 |
| [ECX] | 00 | 001 |
| [EDX] | 00 | 002 |
| [EBX] | 00 | 003 |
| [--][--] | 00 | 004 |
| disp32 | 00 | 005 |
| [ESI] | 00 | 006 |
| [EDI] | 00 | 007 |
| [EAX]+disp8 | 01 | 000 |
| [ECX]+disp8 | 01 | 001 |
| [EDX]+disp8 | 01 | 002 |
| [EBX]+disp8 | 01 | 003 |
| [--][--]+disp8 | 01 | 004 |
| [EBP]+disp8 | 01 | 005 |
| [ESI]+disp8 | 01 | 006 |
| [EDI]+disp8 | 01 | 007 |
| [EAX]+disp32 | 10 | 000 |
| [ECX]+disp32 | 10 | 001 |
| [EDX]+disp32 | 10 | 002 |
| [EBX]+disp32 | 10 | 003 |
| [--][--]+disp32 | 10 | 004 |
| [EBP]+disp32 | 10 | 005 |
| [ESI]+disp32 | 10 | 006 |
| [EDI]+disp32 | 10 | 007 |
| EAX/AX/AL/MM0/XMM0 | 11 | 000 |
| ECX/CX/CL/MM/XMM1 | 11 | 001 |
| EDX/DX/DL/MM2/XMM2 | 11 | 002 |
| EBX/BX/BL/MM3/XMM3 | 11 | 003 |
| ESP/SP/AH/MM4/XMM4 | 11 | 004 |
| EBP/BP/CH/MM5/XMM5 | 11 | 005 |
| ESI/SI/DH/MM6/XMM6 | 11 | 006 |
| EDI/DI/BH/MM7/XMM7 | 11 | 007 |
1.[--][--]表示随后的SIB字节指明寻址方式； 2.Mod为11B时，表示寄存器操作数。对于R/M的每个值，根据指令码与操作数长度属性确定具体的寄存器号。 3.当指令需要第2操作数时，由Reg/Opcode的3位给出。第2操作数只能是寄存器操作数。寄存器的指定方式，与Mod为11B时指定作为第1操作数的寄存器的方式完全相同。
某些ModR/M字节表示的寻找模式，需要SIB字节来补充寻址方式。scale表示比例系数；index表示变址寄存器号；base表示基址寄存器号。使用scale与index的5位定义比例变址寄存器如下：
| 比例变址 | Scale | Index |
| --- | --- | --- |
| [EAX] | 00 | 000 |
| [ECX] | 00 | 001 |
| [EDX] | 00 | 002 |
| [EBX] | 00 | 003 |
| 无 | 00 | 004 |
| [EBP] | 00 | 005 |
| [ESI] | 00 | 006 |
| [EDI] | 00 | 007 |
| [EAX*2] | 01 | 000 |
| [ECX*2] | 01 | 001 |
| [EDX*2] | 01 | 002 |
| [EBX*2] | 01 | 003 |
| 无 | 01 | 004 |
| [EBP*2] | 01 | 005 |
| [ESI*2] | 01 | 006 |
| [EDI*2] | 01 | 007 |
| [EAX*4] | 10 | 000 |
| [ECX*4] | 10 | 001 |
| [EDX*4] | 10 | 002 |
| [EBX*4] | 10 | 003 |
| 无 | 10 | 004 |
| [EBP*4] | 10 | 005 |
| [ESI*4] | 10 | 006 |
| [EDI*4] | 10 | 007 |
| [EAX*8] | 11 | 000 |
| [ECX*8] | 11 | 001 |
| [EDX*8] | 11 | 002 |
| [EBX*8] | 11 | 003 |
| 无 | 11 | 004 |
| [EBP*8] | 11 | 005 |
| [ESI*8] | 11 | 006 |
| [EDI*8] | 11 | 007 |
3位base表示的基址寄存器号，定义如下：
| EAX | ECX | EDX | EBX | ESP | [*] | ESI | EDI |
| --- | --- | --- | --- | --- | --- | --- | --- |
| 000 | 001 | 002 | 003 | 004 | 005 | 006 | 007 |
[*]有两种含义：1.如果Mod为00B，则[scaled index] + disp32，即没有基址寄存器。 2.如果Mod为01B或10B，表示基址寄存器为EBP。
在汇编程序设计中，一般把第1操作数的寻址方式总结为如下8种：
| 寻址方式 | 英文术语 | 举例 |
| --- | --- | --- |
| 立即（数）寻址 | immediate addressing | mov EAX, 01F2H |
| 寄存器寻址 | register addressing | mov EAX, ESI |
| 直接寻址 | direct addressing | mov EAX, DWORD PTR [1FFA00H] |
| 寄存器间接寻址 | register indirect addressing | mov EAX, DWORD PTR [EBX] |
| 基址加变址寻址 | base-plus-index addressing | mov EAX, DWORD PTR [EBX+ESI] |
| 寄存器相对寻址 或基址相对寻址 | register relative addressing | mov EAX, DWORD PTR [EDI+01F4H] |
| 基址相对加变址寻址 | base relative-plus-index addressing | mov EAX, DWORD PTR 01F4H[EDI+EBX] |
| 比例变址寻址 | scaled-index addressing | mov EAX, DWORD PTR 01F4H[EDI*8+EBX] |
综合指令格式中的ModR/M与SIB两个字节的语义规定，指令的第1操作数的寻址方式可总结为4种物理实现：
立即数：表示在指令的“立即数”部分。包括了直接寻址，即立即数作为内存的地址。
寄存器操作数：Mod为11B，根据R/B部分的值、指令码、操作数长度属性，确定具体的寄存器号。
基址相对寻址：即[Reg+disp8或disp32]。包括了寄存器间接寻址。这种情况计算第1操作数地址时使用了1个寄存器。
基址加比例变址的相对寻址：即[BaseReg+IndexReg*scale+disp8或disp32]。这种情况计算第1操作数地址时使用了2个寄存器。