进位/溢出& x86 中的减法
我正在尝试解决溢出问题在 x86 中携带标志。
据我了解,对于有符号 2 的补码的加法,只能通过四种方式之一生成标志(我的示例是 4 位数字):
- pos+pos = neg (溢出)
- 0111 + 0001 = 1000 (7 + 1 = -8)
- pos+neg = pos(进位)
- 0011 + 1110 = 0001 (3 + -2 = 1)
- neg+neg = neg(进位)
- 1111 + 1111 = 1110 (-1 + -1 = -2)
- neg+neg = pos(溢出和进位)
- 1000 + 1001 = 0001 (-8 + -7 = 1)
那么,在 x86 汇编中,从 A 中减去 B 是否会生成与添加 A 和 -B 相同的标志?
I'm trying to wrap my head around overflow & carry flags in x86.
As I understand it, for addition of signed 2's complement numbers, the flags can only be generated in one of four ways (my examples are 4-bit numbers):
- pos+pos = neg (overflow)
- 0111 + 0001 = 1000 (7 + 1 = -8)
- pos+neg = pos (carry)
- 0011 + 1110 = 0001 (3 + -2 = 1)
- neg+neg = neg (carry)
- 1111 + 1111 = 1110 (-1 + -1 = -2)
- neg+neg = pos (overflow & carry)
- 1000 + 1001 = 0001 (-8 + -7 = 1)
So, in x86 assembly, does subracting B from A generate the same flags as adding A and -B?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是一个可能有帮助的参考表。此示例展示了 x86 上的 ADD 和 SUB 指令可能产生的 4 个算术标志的每种组合。 'h' 'ud' 和 'd' 代表每个值的十六进制、无符号十进制和有符号十进制表示。例如,SUB 的第一行显示 0xFF - 0xFE = 0x1,但未设置任何标志。
但是,我认为简短的故事是亚历克斯的答案是正确的。
Here's a reference table that might help. This shows an example of every possible combination of the 4 arithmetic flags that can result from the ADD and SUB instructions on x86. 'h' 'ud' and 'd' stand for hex, unsigned decimal and signed decimal representations of each value. For example, the first row for SUB says 0xFF - 0xFE = 0x1 with no flags set.
But, I think the short story is that Alex's answer is correct.
加法或减法时,进位和溢出值的所有 4 种组合都是可能的。您可以在此答案中查看更多示例。
这个答案包含一个证明,证明您从
AB
获得的进位是相反的从A+(-B)
获得的进位。第一个链接的代码利用此属性将ADC
转换为SBB
。但是,
AB
和A+(-B)
的有符号溢出标志值必须相同,因为它取决于结果是否具有正确的符号位,并且在这两种情况下,符号位都是相同的。All 4 combinations of the carry and overflow values are possible when adding or subtracting. You can see more examples in this answer.
This answer contains a proof of the fact that the carry that you get from
A-B
is the inverse of the carry you get fromA+(-B)
. The code by the first link exploits this property to turnADC
intoSBB
.The signed overflow flag value, however, must be the same for both
A-B
andA+(-B)
because it depends on whether or not the result has the correct sign bit and in both cases the sign bit will be the same.