Math 进位/溢出&;x86中的减法
我试图在x86中绕过溢出和携带标志 据我所知,对于有符号2的补码的加法,标志只能以四种方式之一生成(我的示例是4位数字):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
- 0111+0001=1000(7+1=-8)
- 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))}