在x86中进行/溢出和减法

Rob*_*obz 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)

那么,在x86汇编中,从A中减去B会产生与添加A和-B相同的标志吗?

srk*_*ing 19

这是一个可能有用的参考表.这显示了可能由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
Run Code Online (Sandbox Code Playgroud)

  • @James - 不,引用x86程序员的参考"对于一个字节整数,整数值的范围从-128到+127" (2认同)

Ale*_*nze 9

在加或减时,可以使用进位和溢出值的所有4种组合.您可以在此答案中看到更多示例.

这个答案包含一个证据,证明你得到的携带是你得到A-B的携带的逆A+(-B).第一个链接的代码利用此属性ADC变为SBB.

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