欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

七 Bit filed(三)

七 Bit filed(三)

首先解答上次的悬念.
    "w"位只影响寄存器而不影响指针(pointer,即地址),而指针只能是全寄存器.
    像reg,[reg][reg*4][displacement]这样的地址,所有寄存器可以使用的域都被使用了,但是这里只有一个操作数(即reg)可以是局部寄存器.
    code域指示了寄存器是指针与否.
    在现在的编码系统中,这4个域一共是4*3=12位,被两个字节的[modrm][sib]包含,也包括其中的scale和mod.如果给每一个reg域4 bit,那么仅仅reg域就占用了16bit,在加上scale和mod,那么每条指令都会相应的增大.
    现在你可能明白了汇编器是如何编码/汇编的了.
    看看下面的语句:
    byte  ptr ...
    word  ptr ...
    dword ptr ...
    大多数情况下(操作数默认为32位):
    byte  ptr - 汇编器置w位为 0
    word  ptr - 置w位为1且增加prefix 66h
    dword ptr - 置w位为1
    对于16位的操作数,一般都需要加prefix 66h
    我们回到MUL/IMUL reg opcode:
    MUL   1111011w:11 100 reg
    IMUL  1111011w:11 101 reg
    你一定发现第二个字节仅仅是中间的三位不同(以列分隔).第二个字节就是所谓的ModR/M,它的格式是2 : 3 : 3.
    bits  7,6   :mod
    bits  5,4,3 :code or reg
    bits  2,1,0 :mem or reg
    在OllyDbg中输入以下几条指令:    
    mov   reg,reg
    sub   reg,reg
    add   reg,reg
    and   reg,reg
    它们都是双字节PoCode,且第二个字节都是ModR/M.
    在输入一些使用同样寄存器操作数的指令如:
    mov   ecx,edi
    sub   ecx,edi
    add   ecx,edi
    and   ecx,edi
    你可能会看到他们的第二个字节是一致的.之所以说是可能,是因为这种指令可以有两种编码的方式,呆会你就会明白.
    (在OD中结果如下:
    8BCF  mov  ecx, edi
    2BCF  sub  ecx, edi
    03CF  add  ecx, edi
    21F9  and  ecx, edi
    8BF9  mov  edi, ecx
    2BF9  sub  edi, ecx
    03F9  add  edi, ecx
    21CF  and  edi, ecx ).
    将其中的第二个字节以二进制表示,并且以2 : 3 : 3的格式分隔.通过最后的两个3 bit我们可以看出使用的寄存器.以mov ecx,edi为例,
    8BCF  mov     ecx, edi
    第二个字节即11 001(ecx) 111(edi).
    在这个例子中,第二个字节用于指定寄存器,但并不总是这样,对于某些OpCode,它被用于附加的code位.MUL/iMUL reg就是如此:
    MUL   1111011w:11 [100] reg
    IMUL  1111011w:11 [101] reg
    对于1111011w,100意味着MUL,而101则为IMUL.
    你应该记住的是--如果你不练习,那我这些话对于你没有任何鸟用:
    在OD中输入一些MUL/IMUL指令的OpCode:
    使第一个字节是F7(bit w = 1),使用全寄存器;F6,局部寄存器.
    使第二字节的第一个十六进制数为E,第二个<8,code/reg的最低位为0,即code/reg为100,即MUl;>=8,code/reg的最低位为1,即code/reg为101,即IMUl.
    试着练习下.
    现在你肯定对MUL/IMUL指令比较顺手了,那么你可以试试DIV/IDIV指令:
    DIV   1111011w:11 110 reg
    IDIV  1111011w:11 111 reg
    可以看到只有code/reg域和MUL/IMUL的有些不一样,实际上对于这4条指令:
    code/reg  instruction
    100       MUL
    101       IMUL
    110       DIV
    111       IDIV
    code/reg域决定了这是什么指令(MUL,iMUL,DIV,iDIV).
    不仅仅是MUL,IMUL,DIV,IDIV reg,
    MUL,IMUL,DIV,IDIV [mem]也是如此:
    在OD中输入如下指令:
    MUL   EBX
    IMUL  EBX
    DIV   EBX
    IDIV  EBX
    MUL   [EBX]
    IMUL  [EBX]
    DIV   [EBX]
    IDIV  [EBX]
    将每条指令的第二个字节转化为2 : 3 : 3的格式,然后比较它们的异同.如:
    Second byte     instruction
    11 100 011      MUL EBX
    11 101 011      IMUL EBX
    ......
    (OD的结果如下:
    F7E3  mul     ebx
    F7EB  imul    ebx
    F7F3  div     ebx
    F7FB  idiv    ebx
    F723  mul     dword ptr [ebx]
    F72B  imul    dword ptr [ebx]
    F733  div     dword ptr [ebx]
    F73B  idiv    dword ptr [ebx] ).
    下一次我们将详细讨论modr/m和sib域.

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功