我一直试图让我的头脑围绕溢出与携带(对于ARM7,但足够基本,我的意思是适用于任何东西的术语)。
我想我终于有了它 - 但我想检查我的“真正的基本理解”是否正确,所有复杂性都已消除,是否真的只是归结为:
unsigned => V = 0
V = 1 => bit n is incorrect
C = 1 => bit n+1 'exists'
谢谢,
这些状态位,关于溢出,与unsigned与二进制补码有关。
加法本身是符号无关的,即补码之美。一大块逻辑可用于无符号和有符号的加减法。无符号与有符号加法或减法唯一重要的地方是溢出位、无符号溢出(又名进位位)和有符号溢出(又名溢出)。
由于我们在小学时了解了进位,因此进位位希望更加明显:
7
+4
=====
您需要“随身携带”才能进行添加。二进制中完全相同,只是处理器通常具有固定数量的位置,在纸上,操作的宽度与您拥有多少纸有关。
因此,如果设置了 msbit 的任何加法carry out
,则存在无符号溢出,我们没有足够的位来容纳列数。
现在这导致了一些混乱,因为进位位也被讨论为减法,这成为了一个实现的东西,所以我不一定(也不会亲自)记住 arm 是这样做的,x86 是这样做的,等等。但是请记住,找出二进制补码是什么的一种方法是“反转并加一”。好吧,例如,当您想从 7 中减去 5 时,您在逻辑中要做的不是添加 -5,而是添加5的补码并设置(反转)该carry in
位:
1 <- invert or set the carry in bit
111 <- 7 (0b111)
+ 010 <- ones complement of 5 (0b101)
=====
然后我们做数学:
1111
111
+ 010
=====
010
结果是 2 (2b010) WITH A CARRY OUT?
不,这carry out
并不意味着无符号溢出。在做减法时,carry out
从溢出的角度来看,它是倒置的。这是一些处理器变化的地方。当操作是减法时,有些会反转结果carry flag
,因此上述 ALU 操作可能导致该减法的 acarry flag
为 1 或 acarry flag
为 0,具体取决于处理器,这也意味着在处理器支持的情况下使用借位进行减法,carry in
将在途中反转或不反转。
那么签名溢出呢?
那么让我们看看三个位模式:
unsigned signed
000 0 0
001 1 1
010 2 2
011 3 3
100 4 -4
101 5 -3
110 6 -2
111 7 -1
例如,如果我们要添加位模式 2b011 + 2b010,无符号表示 3+2 = 5,有符号表示 3+2 = -3...嗯,这是错误的。签名的溢出会告诉你。不会为该操作设置无符号溢出,但会设置有carry out
符号溢出。使用 x86 甚至可能存在半溢出和全溢出?不止一个溢出?有人有一个,和东西..AL
AH
AX
反正
0100 < - carry in and out
011
+ 010
======
100
注意carry in
msbit 是 1 而carry out
是 0,这就是我们检测到有符号溢出的方式。
是的,您可以将其视为第 n 位错误,因为符号错误。但是从数学的角度来看并没有错,符号位是错误的,因为没有足够的位来存储答案,如果我们有一个 3 位加法器,则与 7+5 = 12 = 0b1100 的无符号加法没有什么不同将得到 7+5 = 4 并carry out
指示没有足够的空间来存储结果的所有位。无符号溢出。