完整的轉(zhuǎn)換方法需要intel提供免費翻印下載的那本手冊。手冊過于精簡,因此這里給出的例子用于輔助對手冊進(jìn)行理解。假設(shè)讀者閱讀過intel提供的手冊,或其他相關(guān)資料。
x86中大多數(shù)指令的16位與32位版本(指的是寄存器而不是地址)的opcode都是相同的。如果將一個字節(jié)66H加載指令前的話,使用“與缺省不同的位數(shù)”。也就是說,用的操作系統(tǒng)是32位的話,那么使用66H前綴就代表需要對16位的寄存器進(jìn)行操作。
下面對指令A(yù)DD [EDX*8+EBX+256],EBX進(jìn)行翻譯。x86的32位CPU所用的指令集結(jié)構(gòu)是:Prefix | OpCode | ModR/M | SIB | Displacement | Immediate。
指令名ADD,第一個參數(shù)為dword ptr [EDX*8+EBX+256],第二個參數(shù)為EBX。因此應(yīng)該使用下面的opcode進(jìn)行翻譯(見手冊)。
1 01/r ADD,r/m32,r32
r/m32代表由寄存器表達(dá)式計算而成的指針數(shù)值所指向的內(nèi)存中記載的32位數(shù)字,而r32則代表一個32位。這里用的是r/m32和r32而不是r/m16和r/16,因此不需要66H前綴,因此
指令的第一個字節(jié)是01H。
第二個字節(jié)是ModR/M碼,這一個字節(jié)指的是操作數(shù)的形式。我們需要一個r/m32與r/32,因此ModR/M的前兩位是10,因為Mod=10下面的R/M位為100的時候可以使用[SIB+disp32]作為參數(shù),也就是[EDX*8+EBX+256]了,此時SIB=EDX*8+EBX,disp32=256=00 01 00 00。這時我們確定了5個位。再看看opcode,有/r標(biāo)志,也就是說digit那3個位將用來記住第二個參數(shù)EBX,EBX的代號是3,也就是011。將Mod=10,digit=011,R/M=100連起來得到
第二個字節(jié)的值:10011100=9CH。
第三個字節(jié)是SIB,用來表達(dá)EDX*8+EBX。SIB所表示的是Index*Scale+Base,其中Index=EDX=2=010,Base=EBX=3=011,Scale=8=3=11(這里1,2,4,8分別用0,1,2,3來表示,因此8=3)。將它們按照Scale Index Base的順序組合起來,得到
第三個字節(jié)的值:11010011=D3H。
接下來就是disp32了。disp32=256,很容易得出這
4個字節(jié)分別是00H 01H 00H 00H。
于是這個指令的2進(jìn)制碼就是
01 9C D3 00 01 00 00。
接下里看一看Prefix的意思。如果寫的指令是ADD [EDX*8+EBX+256],BX的話,BX是16位,因此32位指針指向的也是16位的兩個字節(jié),所以使用如下opcode:
1 01/r ADD,r/m16,r16
翻譯過程與上面一致,但是需要加上66H前綴使之使用它16位版本的指令。因此這個指令的2進(jìn)制碼就是
66 01 9C D3 00 01 00 00了。
如何檢查上面的翻譯對不對呢?只需要打開vc2008,將匯編代碼寫在__asm{ }里面,然后下個斷點,運行之后用ctrl+alt+D,并在右鍵菜單打開show code bytes選項即可。這里附上從vc2008的調(diào)試其中復(fù)制出來的結(jié)果:
1 106: __asm
2 107: {
3 108: INT 3
4 011A7186 CC int 3
5 109: ADC AL,8
6 011A7187 14 08 adc al,8
7 110: ADC AX,8
8 011A7189 66 83 D0 08 adc ax,8
9 111: ADC EAX,8
10 011A718D 83 D0 08 adc eax,8
11 112: ADD AL,10
12 011A7190 04 0A add al,0Ah
13 113: ADD AX,10
14 011A7192 66 83 C0 0A add ax,0Ah
15 114: ADD EAX,10
16 011A7196 83 C0 0A add eax,0Ah
17 115: ADD AL,DL
18 011A7199 02 C2 add al,dl
19 116: ADD AX,DX
20 011A719B 66 03 C2 add ax,dx
21 117: ADD EAX,EDX
22 011A719E 03 C2 add eax,edx
23 118: ADD BL,[EDX]
24 011A71A0 02 1A add bl,byte ptr [edx]
25 119: ADD BX,[EDX*2]
26 011A71A2 66 03 1C 55 00 00 00 00 add bx,word ptr [edx*2]
27 120: ADD EBX,[EDX*4+8]
28 011A71AA 03 1C 95 08 00 00 00 add ebx,dword ptr [edx*4+8]
29 121: ADD [EDX*8+EBX],BL
30 011A71B1 00 1C D3 add byte ptr [ebx+edx*8],bl
31 122: ADD [EDX*8+EBX],BX
32 011A71B4 66 01 1C D3 add word ptr [ebx+edx*8],bx
33 123: ADD [EDX*8+EBX+256],BX
34 011A71B8 66 01 9C D3 00 01 00 00 add word ptr [ebx+edx*8+100h],bx
35 124: ADD [EDX*8+EBX+256],EBX
36 011A71C0 01 9C D3 00 01 00 00 add dword ptr [ebx+edx*8+100h],ebx
37 125: BSWAP EAX
38 011A71C7 0F C8 bswap eax
39 126: BSWAP EDI
40 011A71C9 0F CF bswap edi
41 127: }
posted on 2009-02-15 23:45
陳梓瀚(vczh) 閱讀(3666)
評論(5) 編輯 收藏 引用 所屬分類:
JIT