减法不等于 x86 上的二进制补码相加。要了解进位标志将假定什么值,您必须改为执行长减法:
0000 0100
- 0000 1100
-------------
1 1111 1000
看看最后有没有借钱?这个借位设置进位标志(即进位等于借位)。
其他一些架构(如 ARM)确实将减法实现为加法,但它们不是将二进制补码相加,而是将一个补码相加和一个额外的进位。这在减 0 时很重要。
例如,您的方法将产生 12 - 0:
0000 1100
+ 0000 0000 (- 0000 0000 => + 0000 0000)
-------------
0 0000 1100
带有清晰的携带。但实际发生的是
0000 1100
+ 1111 1111 (- 0000 0000 => +1111 1111 + 1)
+ 1
-------------
1 0000 1100
随身携带。这个细节很重要,否则与 0 的比较将无法正常工作。在该方案中,只要没有借位,就会指示进位(即进位是补位借位)。
英特尔的方式和 ARM 的方式实际上总是产生相同的结果,除了进位标志正好相反。因此,只要 ARM 设置进位,英特尔就会清除它,反之亦然。
减法语义的两种方法都相当普遍。ARM 方法实现起来稍微容易一些,因为它允许直接使用加法器进行减法,而根本不需要接触进位。使用 Intel 方法,执行减法时必须补充进位和出位,但是这样做的额外门在总体方案中并不重要。另一方面,英特尔的方法对程序员来说更直观,因为如果您将正在执行的操作想象为一个长减法,则将进位标志也表示借位更有意义。