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

How does comparing the Sign and Overflow Flag determine operand relationships?

基于比较有符号整数的跳转使用零、符号和溢出标志来确定操作数之间的关系。 CMP 后有两个带符号的操作数,有三种可能的情况:

  1. ZF = 1 - 目的地 = 来源
  2. SF = OF - 目的地 > 来源
  3. SF != OF - 目的地 < 来源

我无法理解场景 2 和场景 3。我研究了可能的组合并发现它们确实有效 - 但我仍然无法弄清楚它们为何有效。

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

编辑:

大家似乎对我的问题有所了解。基于带符号比较的跳转利用零、符号和进位标志 - 这些包括 JGJL 等。

例如:

mov   al, 1
cmp   al, -1    
jg    isGreater

isGreater: 

跳转是因为Overflow flag = Sign Flag(均为0),说明在有符号比较方面,目标操作数大于源操作数。

如果溢出标志设置为 1 且符号标志设置为 0,则表示目标较小。

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

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

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

 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 的所有可能情况。
如您所见,仅当 SF <> OFA > B,仅当 SF = OF 时才 A < B

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

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

但是这会触发进位标志 (CF) 被设置,non-overflowing 操作不会。
这些不正确的结果仅在计算结果不适合操作数大小时才会出现,解决方案是密切关注进位标志,不要假设 OF 和 SF 处理所有可能的情况。

执行带符号的减法 R = Destination - Source 产生带符号的结果。

假设没有溢出 - 通常的算术定律成立:if R = Destination - Source > 0 然后 目的地 > 来源.
没有溢出意味着 OF = 0 并且 R > 0 意味着 SF = 0。

现在假设有一个溢出 - 让我们称 O 最重要,non-sign,位和 S 符号位.
溢出条件意味着 a) 计算结果的 O 需要借用而结果的 S 不需要或 b) 结果的 O 不需要借,而 S 需要。

在情况 a) 因为结果的 S 不需要借位,操作数的两个 S 位是 (1 , 0) (1, 1) 或 (0, 0).
由于结果的 O 需要借位,因此翻转了第一个源 S 位,我们必须排除第二个和第三个选项。
所以操作数的符号位是 1 和 0(因此 Destination < Source),结果的符号位是 SF = 0 和 OF = 1 根据假设。

情况 b) 因为结果的 S 确实需要借位,所以操作数的两个 S 位是 (0, 1) .
由于 O 不需要借位,第一个操作数 S 位没有改变,我们不需要考虑任何进一步的情况。
所以操作数的符号位是 0 和 1(因此 Destination > Source),结果的符号位是 SF = 1 和 OF = 1 根据假设。

回顾一下:

  • If OF = 0 then Destination > Source => SF = 0.
  • If OF = 1 then Destination > Source => SF = 1.

简而言之OF = SF.