携带/溢出&在x86中减法

时间:2012-01-23 00:07:13

标签: math x86 overflow twos-complement carryflag

我正试着把头包裹在溢出和放大在x86中携带标志。

据我了解,为了添加带符号2的补码数,只能用四种方式之一生成标志(我的例子是4位数):

  1. pos + pos = neg(溢出)
    • 0111 + 0001 = 1000(7 + 1 = -8)
  2. pos + neg = pos(carry)
    • 0011 + 1110 = 0001(3 + -2 = 1)
  3. neg + neg = neg(carry)
    • 1111 + 1111 = 1110(-1 + -1 = -2)
  4. neg + neg = pos(溢出和携带)
    • 1000 + 1001 = 0001(-8 + -7 = 1)
  5. 那么,在x86汇编中,从A中减去B会产生与添加A和-B相同的标志吗?

2 个答案:

答案 0 :(得分:17)

这是一个可能有用的参考表。这显示了可以由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

答案 1 :(得分:7)

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

This answer包含一个证据,证明你从A-B得到的进位是从A+(-B)得到的进位的倒数。第一个链接的代码利用此属性将ADC转换为SBB

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