完整的转换方法需要intel提供免费翻印下载的那本手册。手册过于精简,因此这里给出的例子用于辅助对手册进行理解。假设读者阅读过intel提供的手册,或其他相关资料。
x86中大多数指令的16位与32位版本(指的是寄存器而不是地址)的opcode都是相同的。如果将一个字节66H加载指令前的话,使用“与缺省不同的位数”。也就是说,用的操作系统是32位的话,那么使用66H前缀就代表需要对16位的寄存器进行操作。
下面对指令ADD [EDX*8+EBX+256],EBX进行翻译。x86的32位CPU所用的指令集结构是:Prefix | OpCode | ModR/M | SIB | Displacement | Immediate。
指令名ADD,第一个参数为dword ptr [EDX*8+EBX+256],第二个参数为EBX。因此应该使用下面的opcode进行翻译(见手册)。
1 01/r ADD,r/m32,r32
r/m32代表由寄存器表达式计算而成的指针数值所指向的内存中记载的32位数字,而r32则代表一个32位。这里用的是r/m32和r32而不是r/m16和r/16,因此不需要66H前缀,因此
指令的第一个字节是01H。
第二个字节是ModR/M码,这一个字节指的是操作数的形式。我们需要一个r/m32与r/32,因此ModR/M的前两位是10,因为Mod=10下面的R/M位为100的时候可以使用[SIB+disp32]作为参数,也就是[EDX*8+EBX+256]了,此时SIB=EDX*8+EBX,disp32=256=00 01 00 00。这时我们确定了5个位。再看看opcode,有/r标志,也就是说digit那3个位将用来记住第二个参数EBX,EBX的代号是3,也就是011。将Mod=10,digit=011,R/M=100连起来得到
第二个字节的值:10011100=9CH。
第三个字节是SIB,用来表达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的顺序组合起来,得到
第三个字节的值:11010011=D3H。
接下来就是disp32了。disp32=256,很容易得出这
4个字节分别是00H 01H 00H 00H。
于是这个指令的2进制码就是
01 9C D3 00 01 00 00。
接下里看一看Prefix的意思。如果写的指令是ADD [EDX*8+EBX+256],BX的话,BX是16位,因此32位指针指向的也是16位的两个字节,所以使用如下opcode:
1 01/r ADD,r/m16,r16
翻译过程与上面一致,但是需要加上66H前缀使之使用它16位版本的指令。因此这个指令的2进制码就是
66 01 9C D3 00 01 00 00了。
如何检查上面的翻译对不对呢?只需要打开vc2008,将汇编代码写在__asm{ }里面,然后下个断点,运行之后用ctrl+alt+D,并在右键菜单打开show code bytes选项即可。这里附上从vc2008的调试其中复制出来的结果:
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) 阅读(3630)
评论(5) 编辑 收藏 引用 所属分类:
JIT