art of disassembly----chapter01----lesson9--Opcodes and Mnemonics---04

    编码ADD指令:一些例子

      弄清楚使用如此复杂的体系来编码一条指令,一些小例子很有必要。所以现在来看看如何使用不同的寻址模式来编码一条X86的ADD指令。ADD指令有四个操作码$00,$01,$02,$03 ,使用哪个操作码取决于操作码中的s位及d位。(如Figure 5.15所示) 下面的每个格式描述了如何编码使用不同寻址模式的ADD指令。

       寄存器直接寻址

      

   操作码中的d位及MOD-REG-R/M组织方式的不同导致了一个有趣的问题,那就是一条指令对应两个不同的机器码。例如 add(al,cl)也可以编码为$02,$c8,只要在上面的编码方式中将MOD-REG-R/M 中REG 及R/M域所指定的寄存器进行互换,将操作码中的d位由值0变为值1即可实现。这个问题仅出现于有两个操作数的指令中。

    

    

      直接寻址:

        
      注意上面的指令有错了,机器码$03,$1D,$WW,$YY,$ZZ 对应的指令应该为 ADD(DISP ,EBX)

      

      寄存器间接寻址:

        

     寄存器相对寻址:

                    八位偏移:
       
     
       

        32位偏移:

                 

    比例变址寻址:

            无基地址的情况:
                
           有基地址的情况:
                            
                      
          在这里还是再次做一下总结,当SIB寻址模式没有基地址的时候,,此时,MOD必须为00  ,SIB字节的BASE域为101
          如果SIB寻址模式有基地址并且基地址为ebp时,MOD只能是01 或是10  此时相对比例变址寻址的相对偏移量必为8位或者是32位的了,不再存在没偏移的情况。

       编码立即数操作数

            在MOD-REG-R/M 及SIB这两个字节中,并未出现任何的位组合来让你指定一个立即数操作数。X86使用完全不同的操作码来指定一个立即数操作数。Figure 5.26展示了 ADD指令中有立即数时的基本编码方式。
      
              
         

 出现立即数的ADD指令与标准的ADD指令主要有三个不同。第一,操作码的最高有效值值为1.,这告诉CPU此条指令有一个立即数操作数,这个单一的改变并未告诉CPU将要执行的是ADD指令,我们马上就可以看到。

            第二个不同在于在操作码中没有d位了。很显然的,立即数是不可能作为目的操作数的,所以目的操作数只能为MOD-REG-R/M 字节中由MOD R/M指定的那个操作数。

没有d位,取而代之的是x(符号扩展位)。 这里操作码中的s位与x位要注意一下,s位是指定MOD R/M所指定的那个操作数的大小,而x位表明立即数是否需要进行符号扩展。对于8位的操作数,CPU忽略x位。对于16位或32位操作数来说,x位同时指定了立即数的尺寸。当x位为0时,表明立即数的尺寸同另外一个操作数的尺寸一样;X位为1时,则表明立即数是一个有符号的操作数,另一个操作数的尺寸同立即数的尺寸不一样,在进行运算之前立即数需要进行有符号的扩展。这一点也使程序的更小,因为一般来说,都是把小的立即数加到16位或32位的操作数上的。

          第三个不同在于MOD-REG-R/M 中的REG域。既然立即数是源操作数,MOD-R/M域指定另一个操作数,则REG域这时就空出来了。X86使用这空出来的3个位来作为操作码的扩展。对于ADD指令,这三个位都为0。(其它位值对应于其它不两同的指令)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值