zoukankan      html  css  js  c++  java
  • <转>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
  • 相关阅读:
    洛咕11月月赛部分题解 By cellur925
    POJ 2411 Mondriaan's Dream 【状压Dp】 By cellur925
    Luogu P1637 三元上升子序列【权值线段树】By cellur925
    Luogu P1438无聊的序列【线段树/差分】By cellur925
    Luogu P1558 色板游戏【线段树/状态压缩】By cellur925
    Luogu P4403 [BJWC2008]秦腾与教学评估【二分答案】By cellur925
    Luogu P3941 入阵曲【前缀和】By cellur925
    查询事件状态,mysql查看事件是否开启,设置启动时自动开启方法
    Logback详细整理,基于springboot的日志配置
    使用release自动打包发布正式版详细教程
  • 原文地址:https://www.cnblogs.com/zhangdongsheng/p/2532477.html
Copyright © 2011-2022 走看看