<转>NEG+SBB指令组合的用处

计算机中数码的表示:

定义-》

正数:原码,反码,补码相同。

负数:原码为其对应正数原码最高符号位取反。

   反码为其原码除符号位外都取反。

   补码为其原码除符号位外取反加1。

所以最高位符号位都不变。

补码机:正数补码为其原码,负数为其正数原码取反加1。

NEG指令,相当于0-OPR,并影响进位标志CF.

数学意义上相当于:相当于0-OPR

在计算时实际是以补码形式运算,运算时只有0不影响CF,其它情况都影响CF.为什么,请看以下分析:

(1)假设有数:a=3;

那么:NEG a

分析:a补码为0011,0的补码为0000,所以0000-0011最终会向高位借1所以会有CF=1

(2)假设有数:a=-3;

那么:NEG a

分析:a为负数,补码为1101,所以0000-1101=0011即正数3,所以CF=1

NEG+SBB指令

假设有C语言:
  if(foo() != 0)
  {
    return(FALSE);
  }else{
    return(TURE);
  }
也可以是:
  if(foo() != 0) return(FALSE);
  return TURE;

可以这样汇编(用fasm语法):

  call [foo];调用foo(),返回值在eax中
  neg eax;把操作数按位求反后末位加1, 且if(EAX==0){CF=0}else{CF=1}
  sbb eax,eax; eax-eax-cf ==> (eax)
        ;操作结果:如果foo的返回值不是 0,此时 (eax) = -1
        ;    :如果foo的返回值是 0,此时 (eax) = 0
  inc eax  ; 操作结果:如果foo的返回值不是 0,此时 (eax) = 0
        ;    :如果foo的返回值是 0,此时 (eax) = 1
;===============================================================================
; 进一步解释
;===============================================================================
; if (EAX)=0 则:
; NEG EAX ;等价于: 0 - (EAX) = 0 , 结果: (EAX)=0 ,CF=0
; SBB EAX, EAX ; 等价于 (EAX)-(EAX)-(CF) , 结果为: (EAX)=0
; INC EAX ; ,结果 (EAX)=1

;if EAX!=0 (假设 EAX=5) 则:
; NEG EAX 等价于: 0 - 5 = -5 所以: (EAX)= -5 ,但CF=1
; SBB EAX, EAX 等价于 (EAX)-(EAX)-(CF) 即: (EAX)= -1
; INC EAX 结果 (EAX)=0
;-------------------------------------------------------------------------------
; 以下内容来自网络:
;-------------------------------------------------------------------------------
; 问:
; mov eax,ebx //ebx此时为16位的数,只有bx有值
; neg eax
; sbb eax,eax //eax难道不为零吗?如为零,上两句有何用?
; 此时eax到底是什么值?
; 答:
; 这个主要是sbb指令的作用吧。它除了'源操作数'减去'目的操作数 '外,还得减去'进位标记位CF '。所以,
; sbb eax, eax 的结果是看之前的 CF 的状态了, 你这里就是 neg eax 了.
; neg 指令对 CF 的影响: 如果操作数为0, 则 CF=0 ; 否则, CF=1.
; 所以, 这里的 sbb 指令后 eax 中的结果应该是,
; bx = 0, EAX = 0;
; bx <> 0, EAX = -1
;------------------
; NEG、NOT指令简介
;------------------
;格式:NEG OPR ;B/W执行的操作:←求补这条指令的执行影响全部标志位。
;下面就求补操作时对CF和OF两个标志位的影响做一个分析。求补操格式:NEG OPR ;B/W

;执行的操作:←求补

;这条指令的执行影响全部标志位。

;下面就求补操作时对CF和OF两个标志位的影响做一个分析。
;求补操作即是把操作数按位求反后末位加1,即FFFFH-OPR+1=0-OPR。
;也就是说,对一个操作数求补,相当于用0减去此操作数。
;参加求补运算的操作数当然是有符号数。
;对于CF而言,只有对0求补时,CF=0,其余情况都使CF=1。
;0减去负数应该是正数,但当操作数的值是80H或8000H时,求补后其值保持不变,
;仍为负数,固产生溢出,OF=1。;其余情况都使OF=0。
;

;求反指令NOT的操作是对操作数按位求反,即FFFFH-OPR。所以假定要对AX寄存器中的操作
;数进行求补,那么可以;有如下几种方法:
;
;方法1:NEG AX
;
;方法2:NOT AX
; INC AX
;
;方法3:MOV BX,0
; XCHG AX,BX
; SUB AX,BX
;
;注意:由于求补运算的结果应在AX中,所以方法3中要使用交换指令将AX和BX互换

本人新博客网址为:http://www.hizds.com
本博客注有“转”字样的为转载文章,其余为本人原创文章,转载请务必注明出处或保存此段。c++/lua/windows逆向交流群:69148232
posted @ 2012-06-03 02:35  张东升  阅读(3024)  评论(0编辑  收藏  举报