A = 54 = 00110110 ; B = -77 = 10110111
实际上 -77 是 10110011
所以
a - -b = a + b
设置
0
00110110
+01001101
=========
然后填写
011111000
00110110
+01001101
=========
10000011
msbit 的进位和进位不匹配。操作数的 msbits 也匹配,而结果的 msbits 不匹配。两者都表示有符号溢出。 msbit 的进位为零意味着没有无符号溢出(如果将其视为加法,则不是)。
虽然是减法,但更正确
a - b = a + (-b) 和 -b = ~b + 1
所以你在逻辑中真正看到的是 b 操作数和倒置的进位。
1
00110110
+01001100
==========
当然会给出相同的结果,但它是减法运算而不是加法运算。
你当然可以像在小学时用 10 进制做减法一样容易地用二进制做减法。
00110110
-10110011
==========
与小学不同,我们会将较大的数字放在顶部然后否定结果,但如果需要,我们会从末尾借用...
1 0
00110110
-10110011
==========
借
1 2
00110100
-10110011
==========
1
再借一个
1 22
00110000
-10110011
==========
0000011
再借一个
02 22
00110000
-10110011
==========
10000011
这里的额外位是什么,是使用加法器时的进位,不是借位。当没有发生借位时,进位为 1,当发生借位时,进位为 0。一些体系结构在减法时反转进位并使其成为借位。有些不反转它,你必须知道不进位是借位。
二进制补码的美妙之处在于加法和减法没有无符号与有符号的概念。因此,从逻辑角度来看,位 54 - (-77) 也与 54 - 179 相同,这肯定有借位。用户认为位模式为 -77 或 +179。除法和乘法可以关心,取决于您是否需要填充,并且您对有符号的填充进行签名扩展,而不是对无符号进行零扩展。如果操作数的大小正确,则可以使用有符号和无符号乘法来执行或。但是很大比例的操作数溢出。适当的乘法(结果是操作数位数的 2 倍)对符号很敏感。
54 - -77 = 131 大于 127,所以从有符号运算的角度来看,这个结果不能放在 8 位中。所以这是一个有符号溢出。
54 + 205 作为示例是 259,它大于 256,因此这将是一个无符号溢出(进位位将为加法操作设置)。但这也是 -51, 54 - 51 = 3 不借用,所以这两种观点也适用于此。 54 + 205 = 0x103 表示 0x03,进位为 1。
如果你解决了
操作数的msbits和msbit的进位加在一起
a 操作数 a 的 msbit,b 操作数 b 的 msbit,i msbit 的进位,c msbit 的进位,r msbit 的结果。 i != c 是有符号溢出
ab i cr
00 0 = 00
00 1 = 01 signed overflow
01 0 = 01
01 1 = 10
10 0 = 01
10 1 = 10
11 0 = 10 signed overflow
11 1 = 11
因此,如果 msbit 的进位和进位不匹配,则可以使用该定义,这是有符号溢出。
00 1 = 01 signed overflow
^ ^
11 0 = 10 signed overflow
^ ^
或者你可以使用如果操作数的msbits匹配而结果不匹配的定义是有符号溢出
00 1 = 01 signed overflow
^^ ^
11 0 = 10 signed overflow
^^ ^
00 0 = 00 not a signed overflow
^^ ^
11 1 = 11 not a signed overflow
^^ ^
如果操作数的 msbits 不匹配,则不能有符号溢出。用程序或手工完成 3 位或 4 位操作数的整个组合,从签名的角度检查它们,您会发现这是一个真实的陈述,您不必相信我。
有些人通过 msbit 方法记住它(您可以评估它而无需计算进位和执行),有些人记得进位和执行匹配与否。因此,您将看到逻辑操作数根据作者以一种或另一种方式计算它。
一些架构文档在谈论进位位和溢出位时会产生误导/混淆,而在每次使用溢出确实是有符号溢出位的术语时都没有经过打磨。他们中没有人每次提到它时都将进位位称为无符号溢出/有符号借位/进位位......有些人甚至可能会使用溢出位进行乘法和加法,所以所有这些只会增加混乱。
最好的练习之一是编写一个小程序(只需要大约 20 到 30 行代码)为每个 16*16 操作提供 4 位操作数 0x0 到 0xF 的所有组合。因为这些标志在大多数情况下与比较一起使用,这是一个减法,然后进行减法(反转等并使用加法器)。并计算所有标志 CNVZ。通过该表,您可以了解为什么单独使用 C 标志可以用作大于或小于、N==V、N!=V 等等。 Z 或 C 设置与 C 未设置相同,因此如果翻转操作数,您可以减少大于的倒数小于或等于的指令数量。反转操作数,您不需要使用 z 标志,您可以简单地使用 jc 或 jnc。但是这个练习也显示有符号大于 vs 无符号等等。加上明显有符号和无符号溢出。