比较Sign和Overflow Flag如何确定操作数关系?

时间:2017-02-01 06:12:55

标签: assembly x86 digital-logic

基于比较有符号整数的跳转使用零,符号和溢出标志来确定操作数之间的关系。在带有两个签名操作数的SELECT message FROM tweet t INNER JOIN following f ON t.user_id = f.user_id or t.user_id = f.following_id WHERE t.user_id = 'praveen' and f.following_id in ('bucky','james') 之后,有三种可能的情况:

  1. CMP - 目的地=来源
  2. ZF = 1 - 目的地>源
  3. SF = OF - 目的地<源
  4. 我无法理解方案2和3.我已经研究过可能的组合,看到它们确实有效 - 但我仍然无法弄清楚它们的工作原理。

    有人可以解释为什么Sign和Overflow标志的比较反映了有符号整数关系吗?

    修改:

    似乎对我提出的问题有一些了解。基于签名比较的跳转使用Zero,Sign和Carry标志 - 包括SF != OFJG等。

    例如:

    JL

    跳转是因为溢出标志=符号标志(均为0),表示根据签名比较,目标操作数大于源。

    如果Overflow标志设置为1并且Sign标志设置为0,则表示目标较小。

    我的问题是 - 我似乎无法理解为什么这实际上有效。

2 个答案:

答案 0 :(得分:3)

OF标志跟踪签名溢出,即标志的变化 符号标志显然只是跟踪一个数字是否为负数 两个标志都监视目标操作数的符号或最高有效位(MSB)。

比较CMP指令执行减法 如果A != B且两个操作数具有相同的符号,那么显然会发生以下情况(假设为dword操作数)。

 100 -  200 = -100 (sign change OF=1 + SF=1, ergo A(100) < B(200)).
-100 - -200 =  300 (sign change OF=1 + SF=0, ergo A(-100) > B(-200)).

如果A和B的符号不同,则会发生以下情况。

-100 - 100 = -200 (no sign change, SF=1, OF=0, A < B)
100 - -100 = 200  (no sign change, SF=0, OF=0, A > B)

这涵盖OF + SF的所有可能情况 正如您A > BSF <> OF仅在A < B时才能看到SF = OF

唯一的例外是发生无符号溢出时 假设我们正在比较字节操作数(-128..127)。

126 - -126 = -4 (sign change OF=1 + SF=1, ergo A(126) < B(-126)) ***Oops.

然而,这将触发进位标志(CF)被设置,非溢出操作不会。 只有当计算结果不适合操作数大小时才会出现这些不正确的结果,解决方法是密切关注进位标志,并且不要假设OF和SF处理所有可能的情况。

答案 1 :(得分:3)

执行带符号的减法 R = 目的地 - 会产生签名结果。

假设没有溢出 - 通常的算术法则成立:如果 R = 目的地 - &gt; 0然后目的地&gt; 来源
没有溢出意味着 OF = 0且 R &gt; 0表示 SF = 0.

现在假设存在溢出 - 让我们调用 O 最重要的非符号位和 S 符号位。
溢出条件意味着a)计算结果的 O 需要借用而结果的 S 没有或b)结果的 O 没有需要借用而 S 做了。

如果a)由于结果的 S 不需要借用,操作数的两个 S 位是(1,0)(1,1)或(0,0)。
由于结果的 O 需要借用,因此翻转第一个源 S 位,我们必须排除第二个和第三个选项。
因此操作数符号位为1和0(因此目的地&lt; ),结果的符号位 SF = 0且 OF假设 = 1。

如果b)因为结果的 S 确实需要借位,则操作数的两个 S 位为(0,1)。
由于 O 不需要借用,因此第一个操作数 S 位没有改变,我们不需要考虑任何其他情况。
因此操作数符号位为0和1(因此目的地&gt; ),结果的符号位 SF = 1且 OF假设 = 1。

回顾一下:

  • 如果 OF = 0 ,则目的地&gt; 来源 =&gt; SF = 0
  • 如果 OF = 1 ,则目的地&gt; 来源 =&gt; SF = 1

简而言之 OF = SF