assembly - cmp 时设置 CF

标签 assembly x86

当我们比较两个数字并且一个数字小于另一个数字时,就会设置标志 CF:

mov eax,1
cmp eax,2
jb truWay

二进制形式:

1=00000001 
2=00000010=11111101+1(add. code)=11111110и 
00000001+11111110=11111111(no carry)

为什么指令cmp eax,2设置CF标志?没有进位,或者我错了。

最佳答案

您可以引用these slides了解 ALU 中如何执行减法。

虽然 A - B = A + (-B) 是正确的,并且在补码中是 A + ØB + 1,但这种考虑仅考虑了结果。

用半加器实现的减法器采用以下形式

               A subtracter implemented with half-adders, note the inverted output carry

请注意,CarryOut 位已反转。

您可以通过示例(将大小限制为 4 位)来检查这是否必要且正确:

1 - 2 = 1 + (-2) = 0001b + 1110b = 0|1111b 因为 Ø0 = 1 我们有一个借位

而 2 - 1 则有

2 - 1 = 2 + (-1) = 0010b + 1111b = 1|0001b 因为 Ø1 = 0 我们没有借位

因此,在您的示例中,存在借位,因此 CF 被设置,正是因为 0001b + 1110b 不产生进位。

为了更正式地证明反转执行标志的正确性,可以使用位数归纳。

基本案例
n = 1

这可以用真值表来证明

a  b   a-b (a+¬b+1)  ¬carryOut  Expected borrow
0  0   0+1+1 = 1|0       0           0
0  1   0+0+1 = 0|1       1           1
1  0   1+1+1 = 1|1       0           0
1  1   1+0+1 = 1|0       0           0

感应案例

两个 n 位数字相减时 A = an an-1 ... a0 且 B = bn bn-1 ... b0 我们可以有 A > B、A < B 或 A = B。
在第一种情况下,有一个 k 使得 ak < bk 且 aj = bj 表示所有 j> k 直至 n
条件 ak < bk 意味着 ak = 0 且 bk = 1。
因此,A 和 ØB 等于第 k-1 位,因此只有这么多位会影响进位。
但根据归纳假设,执行是正确的,因此在这种情况下也是正确的。

同样的过程适用于案例 A > B。

情况 A = B 更容易,因为整个操作被简化为 A + ØA + 1,从而简化为 111...1 + 1,总是产生进位,因此没有借位。

关于assembly - cmp 时设置 CF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45631132/

相关文章:

c - Gcc 内联汇编 "' asm' operand has impossible constraints"是什么意思?

c++ - 函数参数在 64 位操作系统的寄存器中传输?

c - 混合 C 和汇编。 64 位 Linux 上的 `Hello World`

无法从 MSR 读回

c - 汇编代码如何确定变量在堆栈中的位置?

linux - 计算 Amd Zen 2 处理器上的 L3 缓存访问事件

c - x86_64 ASM - 指令的最大字节数?

assembly - NASM 错误 : invalid operands in non-64-bit mode

linux - x86 汇编语言 - 如何读取输入的字符数?

assembly - 镜像 Byte/X86 嵌入式程序集(在 Visual Studio 2010 中)