OpCode(操作碼) 和 mnemonic(助記符) 是多對多的
OpCode由6個域組成,其中code是必須的,其他是可選的
a. Prefixes b. code c. ModR/M d. SIB e. Displacement f. Immediate
a. 前綴 b. 操作碼 c. ModR/M d. SIB e. Displacement f. 立即數
AAM AL 除以 10 AL 商 AH 餘數
AAD AL = AH * 10 + AL
EIP 存儲了內存中的某個地址,這個地址告訴CPU,哪裏是當前指令的開始,
但是在指令解碼前,不知道哪裏是指令的結束
1.
00401000 90 NOP
EIP OpCode mnemonic
解碼以後,由於知道NOP只有一個字節,EIP = EIP + 指令的長度(1+1)=00400001
2.
00401000 EB 00 JMP 00401002
00401002 90 NOP
EB佔用1個字節,00佔用1個字節,EIP = EIP + 指令的長度(1+1)=00400002
3.
00401000 EB FE JMP 00401000
00401002 90 NOP
EB佔用1個字節,FE佔用1個字節,EIP = EIP + 指令的長度(1+1)=0xFE+0x2=0x100
由於imm8的關係,0x100只能取00,2個字節的情況下,只能取低1個字節。
真正的底層程序員應該會理解指令的本質,而不僅僅是從指令的字面上去理解它的意思。
4.
00401000 75 01 JNZ SHORT 3 ->
如果不是0,那麼EIP的值是 EIP當前值(00401000)
+ 本條指令的立即數(01)+本條指令的長度(2)
00401002 04 AC ADD AL, 0AC
所以會跳到04 AC的中間執行
Perfixes 前綴:
1. 所有Prefixes的長度都是1個字節。
2. 一個OpCode可能會有幾個Prefixes。
3. 如果有多個Prefixes,那麼它們的順序可以打亂。
4. 如果Prefixes不能對隨它之後的OpCode起作用,那麼它就會被忽略。
Perfixes分類:
1. Change DEFAULT operand size.(66) 切換默認操作數大小,是開關標記
2. Change DEFAULT address size.(67) 切換默認地址的大小,是開關標記
3. Repeat prefixes.(F2 F3) 重複前綴
4. Segment override prefixes (change DEFAULT segment).
2E - CS 36 - SS 3E - DS 26 - ES 64 - FS 65 - GS
5. LOCK prefix.(F0) 鎖前綴
例:8A 00 MOV AL, [EAX] -> 67 8A 00 MOV AL, [BX+SI]
地址由原來的32位的[EAX]變成了16位的[BX+SI]
在16位的地址模式中無法完全使用32位中的對應的地址模式,
兩種模式中的寄存器有着一定的區別。
Repeat Prefixes(F2 F3)
Repeat Prefixes通常是與movs scas cmps 等串指令搭配使用
F2 REPNE F3 REP/REPE
重複執行後面的串操作指令,每次重複前先判斷(E)CX的值,> 0 把(E)CX的值減1,
再重複執行後面的串操作指令 =0退出
和LOOP指令的區別是:LOOP指令先把(E)CX的值減1,再判斷是否爲0
有3種Repeat Prefixes的助記符:rep/repe/repene,但是隻有2個OpCode:F2 F3
如果某些指令只使用前綴rep,那麼這裏的rep可以用repe或者repne來代替
重複串指令時可能會改變某些標誌位(例如ZF),在這種情況下,有些指令與重複前綴
搭配使用時,F2和F3會把最後一位與標誌位ZF進行比較,
如果它們不相同,則重複串指令的操作將會結束。而有些指令不用進行這個比較的操作,
因此標誌位ZF對這些指令的運行結果無影響。
11110010 F2 11110011 F3
Repeat Prefixes的結束條件 REP = ECX=0 REPE = ECX=0 && ZF=0 REPNE = ECX=0 && ZF=1
CS: For EIP pointer
ES: 目的操作數是內存單元的串指令(movs, cmps等),在這裏源操作數是儲存在段DS裏面
SS: 堆棧操作(push, pop等)
DS: 剩下的數據操作指令
FS一般是由SEH(結構化異常處理)所使用
1個字節如果被轉換成2進制,是由8bit來表示,不足8bit高位補0
ModR/M是由Mod Reg/Opcode R/M三個部分組成的
每個部分所佔的bit大小爲:
Mod: 6 7
Reg/Opcode: 3 4 5
R/M: 0 1 2
分析下面2條機器指令
8B F9(MOV EDI, ECX) 2B F9(SUB EDI, ECX)
因爲沒有前綴,F9是MOD Reg/OpCode R/M, F9(11111001)按照2:3:3拆開,
MOD=11
Reg/OpCode=111
/ 表示或,意思是這個地方可以表示爲Reg或OpCode(由Code來決定),
如果它是表示OpCode,則這個指令必定是2字節的。
Reg由3個bit組成,所以有8種可能:
000 - EAX 001 - ECX 010 - EDX 011 - EBX 100 - ESP
101 - EBP 110 - ESI 111 - EDI
R/M=001
結論
Mod=11 表示應該查看Mod爲11的那一欄
Reg/Opcode=111 表示的是寄存器EDI
R/M=001 表示的是ECX