不是全部的指令都是,看到opcode就知道有多長(定長指令),當指令中出現內存操做對象的時候,就須要在操做碼後面附加一個字節來進行補充說明,這個字節被稱爲ModR/M。編碼
該字節的8個位被分紅了三部分:操作系統
其中,Reg/Opcode(第三、四、5位,共3個字節)描述指令中的G部分,即寄存器3d
Mod(第六、7位)和R/M(第0、一、2位)共同描述指令中的E部分,即寄存器/內存code
因特爾白皮書:對象
0x88 MOV Eb, Gb G:通用寄存器blog
0x89 MOV Ev, Gv E:寄存器/內存內存
0x8A MOV Gb, Eb b:字節im
0x8B MOV Gv, Ev v:Word, doubleword or quadword(這個看操做系統,是多少位就多少位)d3
MOV Eb, Gb: Gb決定了是8位的通用寄存器,具體是哪個通用寄存器還要看ModR/M的3,4,5部分總結
01:00 000 001
前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面能夠知道 Reg/Opcode部分是 000,至關於0號寄存器,即[EAX],可是因爲是8位,因此是AL
012位和67位組合起來是00 001
是[ECX],因此這條指令應該是:mov byte ptr ds:[ECX],AL
MOV Eb, Gb: Gb決定了是8位的通用寄存器,具體是哪個通用寄存器還要看ModR/M的3,4,5部分
01:00 010 101
前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面能夠知道 Reg/Opcode部分是 001,至關於2號寄存器,即[ECX],可是因爲是8位,因此是CL
012位和67位組合起來是00 101
能夠看到這裏並非咱們想的EBP,這是由於EBP指向棧底,而[EBP]一般存儲上一個EBP,因此[EBP]無數據操做意義,Inter將這個編碼廢棄,改成當即數尋址
例如當操做指令爲88 81 12 34 56 78時,其對應的彙編爲MOV BYTE PTR DS:[ECX+78563412],AL
disp32其實是個偏移
再看這幾個 ESP都沒有對應的值
這是由於:ESP指向棧頂,是浮動的,不肯定的,Inter將這個編碼廢棄,由另外的格式來講明。
仍是看一下
MOV Ev, Gv : Gv與我當前的x32dedug決定了是32位的通用寄存器,具體是哪個通用寄存器還要看ModR/M的3,4,5部分
01:00 000 011
前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面能夠知道 Reg/Opcode部分是 000,至關於0號寄存器,即EAX
012位和67位組合起來是00 011
因此是[EBX],這條指令是:mov dword ptr ds:[ebx],eax
這裏只列舉一個,這個指令與0x88區別就是位數的差異
MOV Gb, Eb: Gb決定了是8位的通用寄存器,具體是哪個通用寄存器還要看ModR/M的3,4,5部分
01:00 000 111
前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面能夠知道 Reg/Opcode部分是 000,至關於0號寄存器,即EAX,但咱們這裏是byte因此是al
012位和67位組合起來是00 111
是EDI,這條指令命令爲:mov al,byte ptr ds:[edi]
MOV Gv, Ev : Gv與我當前的x32dedug決定了是32位的通用寄存器,具體是哪個通用寄存器還要看ModR/M的3,4,5部分
01:00 100 110
前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面能夠知道 Reg/Opcode部分是 100,至關於5號寄存器,即ESP
012位和67位組合起來是00 110
esi,mov esp,dword ptr ds:[esi]
MOV Gv, Ev : Gv與我當前的x32dedug決定了是32位的通用寄存器,具體是哪個通用寄存器還要看ModR/M的3,4,5部分
01:01 100 110
前兩位是Mod ;3,4,5位是Reg/Opcode;0,1,2位是R/M
由上面能夠知道 Reg/Opcode部分是 100,至關於5號寄存器,即ESP
012位和67位組合起來是01 110
[esi+12],mov esp.dword ptr ds:[esi+12]
當Mod = 00時,ModR/M字節經過寄存器直接進行內存尋址
當Mod = 01時,ModR/M字節經過寄存器+I8進行內存尋址(I爲當即數,即8位當即數)
當Mod = 10時,ModR/M字節經過寄存器+I32進行內存尋址
當Mod = 11時,ModR/M字節直接操做兩個寄存器