为什么当零是被减数时在减法期间设置进位标志?
Why is the Carry Flag set during a subtraction when zero is the minuend?
目前我正在编写自己的小库,用于对非常大的无符号整数进行算术和逻辑运算。为了提高性能,我决定在汇编中实现一些功能。所以这是我的问题。
在减去两个无符号整数时,当我从 0 中减去任何数字时设置进位标志。
但是为什么Carry Flag会设置在这种情况下呢?进位标志仅在发生溢出时设置,但如果我从零中减去任何数字,我就不会溢出。
还是我错了?
进位标志是最高有效位 (MSb) 的进位或借位:
CF (bit 0) Carry flag — Set if an arithmetic operation generates a carry or a borrow out of the mostsignificant bit of the result; cleared otherwise. This flag indicates an overflow condition for
unsigned-integer arithmetic. It is also used in multiple-precision arithmetic.
不要将 CF 与符号位相关联,在减法中,只要被视为无符号的被减数小于被视为无符号的减数,就会设置 CF。
这等效于溢出条件,对于有符号数,等效标志为 OF。
对于(不必要的?)视觉线索,在这个 4-5 操作中,是第二个借用,红色那个,设置了 CF
如果你从零减去,自然会出现任何数字,但零本身,你将始终设置 CF,因为减数至少设置了一位。
最后,一些指令允许您在不影响 CF 的情况下更改符号位(例如,请参阅逻辑运算或 neg
的行为)。
我们从小学就知道 a - b = a + (-b)。这就是逻辑的运作方式,我们不减去我们添加负数。我们还从初学者编程中了解到 类,使用二进制补码可以得到负数,然后取反并加一。 a - b = a + (~b) + 1。我们也从小学就知道了携带的概念。 9+3 = 2 携带一个。二进制也一样,有两个操作数,你可以让 1 + 1 = 0 携带一个。所以逻辑中的每一列都需要一个进位。每一个都是三位进两位出,加进位进位和结果出位的两个操作数。由于这些逻辑块中的每一个都有一个输入位,进位,第一个进位的正常加法是零,但对于减法,我们可以使进位为 1 并将第二个操作数取反以获得 a + b = a + (~ b) + 1
所以减法就是加法,如果你通过几个简单的例子,或者最好自己尝试操作数的每三位组合。你会看到没有符号和无符号的加法(或减法),二进制补码编码的美妙之处。
知道了所有这些,减法就是加法,加法我们在UNSIGNED溢出时得到一个进位,有符号溢出位是当msbit的进位和进位不匹配时,通常表示为V标志.现在有些架构,因为它们已经在输入的路上反转了 b 操作数,并且在输入的路上反转了进位,所以它们在输出的时候反转了进位。有些不要。因此,您必须查看您的特定体系结构,以了解进位是否被视为无符号加法溢出或是否是借位。或者不借什么的。
零减去某些东西并不总是会有加法的进位。
0b000 - 0b111
0001
000
+ 000
=====
001
加法的进位为零。您的架构可能会选择保持原样,也可能会选择反转并称之为借用。
在一个体系结构家族中。所有 x86 或所有 ARM 很可能会永远以同样的方式继续这样做。但是没有理由期望 ARM 和 MIPS 以及 x86 和 XYZ 都以同样的方式来做。
从术语的角度来看,将其反转并将其定义为借用是有意义的。
请注意,所有 (signed/unsigned) 大于、小于、大于或等于、小于或等于的定义均基于该体系结构的 carry/borrow 选择,您无法翻译那些跨体系结构的标志比较,除非它们具有相同的定义。
目前我正在编写自己的小库,用于对非常大的无符号整数进行算术和逻辑运算。为了提高性能,我决定在汇编中实现一些功能。所以这是我的问题。 在减去两个无符号整数时,当我从 0 中减去任何数字时设置进位标志。
但是为什么Carry Flag会设置在这种情况下呢?进位标志仅在发生溢出时设置,但如果我从零中减去任何数字,我就不会溢出。 还是我错了?
进位标志是最高有效位 (MSb) 的进位或借位:
CF (bit 0) Carry flag — Set if an arithmetic operation generates a carry or a borrow out of the mostsignificant bit of the result; cleared otherwise. This flag indicates an overflow condition for unsigned-integer arithmetic. It is also used in multiple-precision arithmetic.
不要将 CF 与符号位相关联,在减法中,只要被视为无符号的被减数小于被视为无符号的减数,就会设置 CF。
这等效于溢出条件,对于有符号数,等效标志为 OF。
对于(不必要的?)视觉线索,在这个 4-5 操作中,是第二个借用,红色那个,设置了 CF
如果你从零减去,自然会出现任何数字,但零本身,你将始终设置 CF,因为减数至少设置了一位。
最后,一些指令允许您在不影响 CF 的情况下更改符号位(例如,请参阅逻辑运算或 neg
的行为)。
我们从小学就知道 a - b = a + (-b)。这就是逻辑的运作方式,我们不减去我们添加负数。我们还从初学者编程中了解到 类,使用二进制补码可以得到负数,然后取反并加一。 a - b = a + (~b) + 1。我们也从小学就知道了携带的概念。 9+3 = 2 携带一个。二进制也一样,有两个操作数,你可以让 1 + 1 = 0 携带一个。所以逻辑中的每一列都需要一个进位。每一个都是三位进两位出,加进位进位和结果出位的两个操作数。由于这些逻辑块中的每一个都有一个输入位,进位,第一个进位的正常加法是零,但对于减法,我们可以使进位为 1 并将第二个操作数取反以获得 a + b = a + (~ b) + 1
所以减法就是加法,如果你通过几个简单的例子,或者最好自己尝试操作数的每三位组合。你会看到没有符号和无符号的加法(或减法),二进制补码编码的美妙之处。
知道了所有这些,减法就是加法,加法我们在UNSIGNED溢出时得到一个进位,有符号溢出位是当msbit的进位和进位不匹配时,通常表示为V标志.现在有些架构,因为它们已经在输入的路上反转了 b 操作数,并且在输入的路上反转了进位,所以它们在输出的时候反转了进位。有些不要。因此,您必须查看您的特定体系结构,以了解进位是否被视为无符号加法溢出或是否是借位。或者不借什么的。
零减去某些东西并不总是会有加法的进位。
0b000 - 0b111
0001
000
+ 000
=====
001
加法的进位为零。您的架构可能会选择保持原样,也可能会选择反转并称之为借用。
在一个体系结构家族中。所有 x86 或所有 ARM 很可能会永远以同样的方式继续这样做。但是没有理由期望 ARM 和 MIPS 以及 x86 和 XYZ 都以同样的方式来做。
从术语的角度来看,将其反转并将其定义为借用是有意义的。
请注意,所有 (signed/unsigned) 大于、小于、大于或等于、小于或等于的定义均基于该体系结构的 carry/borrow 选择,您无法翻译那些跨体系结构的标志比较,除非它们具有相同的定义。