我需要一种简洁的方式将 x86 溢出标志表示为两个操作数的函数。我知道两个操作数具有相同符号但结果具有不同符号时的核心集。
例如,
添加 SRC[31..0]、DEST[31..0]
OF 可以合理地表示为 SRC 和 DEST 位的“单线”布尔函数吗?
由于溢出标志是符号位进位与符号位进位的异或,可以表示为:
((SRC[31..0] + DEST[31..0]) shr 32) xor ((SRC[30..0] + DEST[30..0]) shr 31)
这是您如何表达两个有符号(2 的补码)32 位整数相加的有符号溢出标志值:
OV = ((( SRC XOR DST ) XOR 80000000H) AND (( SRC + DST ) XOR SRC ) AND 80000000H) ≠ 0
SRC和DST是整个 32 位整数值。
该表达式本质上比较了和的符号和加数的符号。
仅根据单个位来表示溢出不是很实用,因为您需要有效地复制一个完整的 32 位加法器。这不是一个好的候选人。
如果您想要一个类似的减法表达式,请尝试推导它,或者只用加法表示减法,就像在这个答案Sbb()
中的函数中所做的那样。应该不难。
使用测试来确保您的代码有效也是一个好主意。您甚至可以编写一个用于加法/减法的小型汇编程序,它会返回溢出标志并使用它来测试单行代码的正确性。