加减运算电路示意图

一个加法器如何完成加减法

图中的 XX、YY 是两个 nn 位操作数,FF 是保留的 nn 位结果。Sub 同时控制 MUX 和加法器最低位的初始进位 CinC_{\mathrm{in}}:

Sub MUX 送入加法器的数 CinC_{\mathrm{in}} 加法器完成的运算
00 YY 00 X+YX+Y
11 Y‾\overline Y 11 X+Y‾+1X+\overline Y+1,即 X−YX-Y

这里的 Y‾\overline Y 是将 nn 位 YY 逐位取反。因为在固定位数下 −Y≡Y‾+1(mod2n)-Y\equiv\overline Y+1\pmod{2^n},减法也能交给同一个加法器完成。反相器产生 Y‾\overline Y,MUX 根据 Sub 选择 YY 或 Y‾\overline Y;Sub 还直接作为 CinC_{\mathrm{in}}。

重点: 加法选 YY、初始进位为 00;减法选 Y‾\overline Y、初始进位为 11。

以 4 位无符号数的 5−35-3 为例,X=0101X=0101、Y=0011Y=0011,Sub 为 11:

  0101     X = 5
+ 1100     Y 按位取反
+    1     Cin
------
1 0010

结果 F=0010F=0010,即 22;左边额外的 11 是最高位的进位 CoutC_{\mathrm{out}}。

为什么只保留低 nn 位

nn 位的 FF 只能保存运算结果的低 nn 位,相当于对 2n2^n 取模:

F={(X+Y) mod 2n,Sub=0,(X+Y‾+1) mod 2n,Sub=1.F= \begin{cases} (X+Y)\bmod 2^n, & \mathrm{Sub}=0,\\ (X+\overline Y+1)\bmod 2^n, & \mathrm{Sub}=1. \end{cases}

例如,4 位运算 1111+0001=1 00001111+0001=1\,0000,所以 F=0000F=0000,额外的 11 进入 CoutC_{\mathrm{out}}。

电路只处理位串,不决定它们是有符号数还是无符号数。 同一个 11111111,按 4 位无符号数解释是 1515,按 4 位补码解释是 −1-1。因此,同一个 FF 可以有不同的数值含义,还要结合状态标志判断本次运算。

四个状态标志

标志 含义 如何判断
ZF(Zero Flag,零标志) 结果是否为零 F=0F=0 时为 11
SF(Sign Flag,符号标志) 结果的最高位 等于 FF 的最高位
CF(Carry Flag,进位标志) 无符号加法的进位、无符号减法的借位 加法看 CoutC_{\mathrm{out}};减法按本文教材约定看 Cout‾\overline{C_{\mathrm{out}}}
OF(Overflow Flag,溢出标志) 有符号补码运算是否超出表示范围 按操作数与结果的符号判断

ZF 与 SF

F=0000F=0000 时,ZF 为 11;例如计算 X−YX-Y 得到零,可据此判断两个 nn 位操作数相等。

SF 直接复制 FF 的最高位。例如 F=1110F=1110 时,SF 为 11。但 SF 不能单独说明真实计算结果是否为负数:若 OF 为 11,保留下来的符号位可能已因溢出而变号。

CF:无符号进位或借位

加法产生最高位进位时,CF=Cout=1CF=C_{\mathrm{out}}=1。例如 4 位无符号数 15+115+1 得到 1 00001\,0000,超出无符号范围 0∼150\sim15,因此 CF 为 11。

减法在本电路中通过 X+Y‾+1X+\overline Y+1 实现。此时 Cout=1C_{\mathrm{out}}=1 表示无符号数 X≥YX\ge Y,没有借位;Cout=0C_{\mathrm{out}}=0 表示 X<YX<Y,发生借位。按本文教材的 CF 约定:

CF={Cout,Sub=0,Cout‾,Sub=1.CF= \begin{cases} C_{\mathrm{out}}, & \mathrm{Sub}=0,\\ \overline{C_{\mathrm{out}}}, & \mathrm{Sub}=1. \end{cases}

因此,上面的 5−35-3 有 Cout=1C_{\mathrm{out}}=1、CF=0CF=0;而 4 位无符号数 3−53-5 算得 F=1110F=1110、Cout=0C_{\mathrm{out}}=0、CF=1CF=1,表示发生借位。

OF:有符号溢出

OF 判断真实结果是否超出 nn 位补码范围。例如 4 位补码只能表示 −8∼7-8\sim7。计算 7+37+3 得到 F=1010F=1010,它按补码解释为 −6-6,但真实结果 1010 超过上限,所以 OF=1OF=1。

符号判断规则是:同号相加,结果变号则溢出;异号相减,结果与被减数变号则溢出。 也可以比较进入与离开符号位的两次进位:不同则 OF 为 11。

CF 与 OF 可以不同

4 位运算 FF CF OF 原因
1111+00011111+0001 00000000 11 00 无符号数 15+115+1 超出范围;补码 −1+1=0-1+1=0 正常
0111+00110111+0011 10101010 00 11 无符号数 7+3=107+3=10 正常;补码 7+3=107+3=10 超出范围

记住: CF 反映无符号运算的进位或借位,OF 反映有符号补码运算的溢出;二者要分别判断。

用减法比较大小

比较两个相同位数的数 AA 和 BB 时,先计算 A−BA-B,再根据数的解释方式读取相应标志。无符号数主要看 ZF、CF;有符号补码数主要看 ZF、SF、OF。

无符号数比较

减法中,ZF 为 11 表示结果为零;按本文的 CF 约定,CF 为 11 表示发生借位,即 A<BA<B。因此:

条件 关系
ZF=1ZF=1 A=BA=B
ZF=0ZF=0 且 CF=0CF=0 A>BA>B
CF=1CF=1 A<BA<B

例如,用 3 位无符号数计算 000−001000-001,保留的结果为 111111:结果非零,且减法发生借位,所以 ZF=0ZF=0、CF=1CF=1,判断 0<10<1。这里不能把 111111 按无符号数读成 77 后直接比较。

有符号数比较

若把 AA、BB 当作补码有符号数,发生溢出时,结果符号位 SF 可能与真实差值的正负相反。用 SF⊕OFSF\oplus OF 修正符号,再结合 ZF 判断:

条件 关系
ZF=1ZF=1 A=BA=B
ZF=0ZF=0 且 SF=OFSF=OF A>BA>B
ZF=0ZF=0 且 SF≠OFSF\ne OF A<BA<B

例如,3 位补码中 011=+3011=+3、101=−3101=-3:

  • +3−(−3)+3-(-3) 的真实差值为 +6+6,超出 −4∼3-4\sim3 的范围;保留结果为 110110,故 ZF=0ZF=0、SF=1SF=1、OF=1OF=1。由于 SF=OFSF=OF,判断 +3>−3+3>-3。
  • −3−(+3)-3-(+3) 的真实差值为 −6-6,同样溢出;保留结果为 010010,故 ZF=0ZF=0、SF=0SF=0、OF=1OF=1。由于 SF≠OFSF\ne OF,判断 −3<+3-3<+3。

对照记忆: 无符号比较看 ZF、CF;有符号比较看 ZF、SF⊕OFSF\oplus OF。


其实我有点懵逼,
之后还得再多看几遍。
出生时早知道智力分配多些点数了😇。