Math 进位/溢出&;x86中的减法

Math 进位/溢出&;x86中的减法,math,x86,overflow,twos-complement,carryflag,Math,X86,Overflow,Twos Complement,Carryflag,我试图在x86中绕过溢出和携带标志 据我所知,对于有符号2的补码的加法,标志只能以四种方式之一生成(我的示例是4位数字): pos+pos=neg(溢出) 0111+0001=1000(7+1=-8) pos+neg=pos(进位) 0011+1110=0001(3+-2=1) 负+负=负(进位) 1111+1111=1110(-1+-1=-2) 负+负=位置(溢出和携带) 1000+1001=0001(-8+-7=1) 因此,在x86汇编中,从A中减去B是否会生成与添加A和-B

我试图在x86中绕过溢出和携带标志

据我所知,对于有符号2的补码的加法,标志只能以四种方式之一生成(我的示例是4位数字):

  • pos+pos=neg(溢出)
    • 0111+0001=1000(7+1=-8)
  • pos+neg=pos(进位)
    • 0011+1110=0001(3+-2=1)
  • 负+负=负(进位)
    • 1111+1111=1110(-1+-1=-2)
  • 负+负=位置(溢出和携带)
    • 1000+1001=0001(-8+-7=1)

  • 因此,在x86汇编中,从A中减去B是否会生成与添加A和-B相同的标志?

    在添加或减去时,进位值和溢出值的所有4种组合都是可能的。您可以在中看到更多示例

    包含从
    a-B
    获得的进位与从
    a+(-B)
    获得的进位相反这一事实的证明。第一个链接的代码利用此属性将
    ADC
    转换为
    SBB


    但是,有符号溢出标志值对于
    A-B
    A+(-B)
    都必须相同,因为这取决于结果是否具有正确的符号位,并且在这两种情况下,符号位将相同。

    这里有一个参考表可能会有所帮助。这显示了x86上的ADD和SUB指令可能产生的4个算术标志的每个可能组合的示例。”h“ud”和“d”代表每个值的十六进制、无符号十进制和有符号十进制表示形式。例如,SUB的第一行表示0xFF-0xFE=0x1,未设置任何标志

    但是,我认为简短的故事是亚历克斯的答案是正确的

     ADD
           A                   B                   A + B              Flags  
     ---------------     ----------------    ---------------      -----------------
     h  |  ud  |   d   | h  |  ud  |   d   | h  |  ud  |   d   | OF | SF | ZF | CF
     ---+------+-------+----+------+-------+----+------+-------+----+----+----+---
     7F | 127  |  127  | 0  |  0   |   0   | 7F | 127  |  127  | 0  | 0  | 0  | 0
     FF | 255  |  -1   | 7F | 127  |  127  | 7E | 126  |  126  | 0  | 0  | 0  | 1
     0  |  0   |   0   | 0  |  0   |   0   | 0  |  0   |   0   | 0  | 0  | 1  | 0
     FF | 255  |  -1   | 1  |  1   |   1   | 0  |  0   |   0   | 0  | 0  | 1  | 1
     FF | 255  |  -1   | 0  |  0   |   0   | FF | 255  |  -1   | 0  | 1  | 0  | 0
     FF | 255  |  -1   | FF | 255  |  -1   | FE | 254  |  -2   | 0  | 1  | 0  | 1
     FF | 255  |  -1   | 80 | 128  | -128  | 7F | 127  |  127  | 1  | 0  | 0  | 1
     80 | 128  | -128  | 80 | 128  | -128  | 0  |  0   |   0   | 1  | 0  | 1  | 1
     7F | 127  |  127  | 7F | 127  |  127  | FE | 254  |  -2   | 1  | 1  | 0  | 0
    
    
     SUB
           A                   B                   A - B              Flags  
     ---------------     ----------------    ---------------      -----------------
     h  |  ud  |   d   | h  |  ud  |   d   | h  |  ud  |   d   || OF | SF | ZF | CF
    ----+------+-------+----+------+-------+----+------+-------++----+----+----+----
     FF | 255  |  -1   | FE | 254  |  -2   | 1  |  1   |   1   || 0  | 0  | 0  | 0
     7E | 126  |  126  | FF | 255  |  -1   | 7F | 127  |  127  || 0  | 0  | 0  | 1
     FF | 255  |  -1   | FF | 255  |  -1   | 0  |  0   |   0   || 0  | 0  | 1  | 0
     FF | 255  |  -1   | 7F | 127  |  127  | 80 | 128  | -128  || 0  | 1  | 0  | 0
     FE | 254  |  -2   | FF | 255  |  -1   | FF | 255  |  -1   || 0  | 1  | 0  | 1
     FE | 254  |  -2   | 7F | 127  |  127  | 7F | 127  |  127  || 1  | 0  | 0  | 0
     7F | 127  |  127  | FF | 255  |  -1   | 80 | 128  | -128  || 1  | 1  | 0  | 1
    

    您的表很有用,但127--1是128而不是-128。@James-No,引用x86程序员参考资料“字节整数的整数值范围为-128到+127”很好地解释了如何系统地确定进位和溢出。对于加法和减法。8位2补128(0x80)=-128(0x80)如果显示为有符号数,则正确的形式为-128,因为表中显示的是有符号数而非无符号数。它是一个溢出,如所示:127--1=-128如果它没有溢出,那么结果将是+128。(需要9位)另请参阅中的和其他链接。如果有人正在根据ADC实现SBB的x86语义,请注意:SBB{inputs(A,b,cf),outputs(out,of,sf,zf,af,pf,cf)}=ADC{inputs(A,NOT(b),NOT(cf)),outputs(out,of,sf,zf,NOT(cf))}