基于比较有符号整数的跳转使用零,符号和溢出标志来确定操作数之间的关系。在带有两个签名操作数的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')
之后,有三种可能的情况:
CMP
- 目的地=来源ZF = 1
- 目的地>源SF = OF
- 目的地<源我无法理解方案2和3.我已经研究过可能的组合,看到它们确实有效 - 但我仍然无法弄清楚它们的工作原理。
有人可以解释为什么Sign和Overflow标志的比较反映了有符号整数关系吗?
修改:
似乎对我提出的问题有一些了解。基于签名比较的跳转使用Zero,Sign和Carry标志 - 包括SF != OF
,JG
等。
例如:
JL
跳转是因为溢出标志=符号标志(均为0),表示根据签名比较,目标操作数大于源。
如果Overflow标志设置为1并且Sign标志设置为0,则表示目标较小。
我的问题是 - 我似乎无法理解为什么这实际上有效。
答案 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 > B
和SF <> 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 = SF 。