yukki.cn / writing / post-20260926-221841
加减运算电路
梳理加减运算电路、ZF、SF、CF、OF 状态标志,以及有符号数和无符号数的大小比较。

一个加法器如何完成加减法
图中的 X、Y 是两个 n 位操作数,F 是保留的 n 位结果。Sub 同时控制 MUX 和加法器最低位的初始进位 Cin:
| Sub |
MUX 送入加法器的数 |
Cin |
加法器完成的运算 |
| 0 |
Y |
0 |
X+Y |
| 1 |
Y |
1 |
X+Y+1,即 X−Y |
这里的 Y 是将 n 位 Y 逐位取反。因为在固定位数下 −Y≡Y+1(mod2n),减法也能交给同一个加法器完成。反相器产生 Y,MUX 根据 Sub 选择 Y 或 Y;Sub 还直接作为 Cin。
重点: 加法选 Y、初始进位为 0;减法选 Y、初始进位为 1。
以 4 位无符号数的 5−3 为例,X=0101、Y=0011,Sub 为 1:
0101 X = 5
+ 1100 Y 按位取反
+ 1 Cin
------
1 0010
结果 F=0010,即 2;左边额外的 1 是最高位的进位 Cout。
为什么只保留低 n 位
n 位的 F 只能保存运算结果的低 n 位,相当于对 2n 取模:
F={(X+Y)mod2n,(X+Y+1)mod2n,Sub=0,Sub=1.
例如,4 位运算 1111+0001=10000,所以 F=0000,额外的 1 进入 Cout。
电路只处理位串,不决定它们是有符号数还是无符号数。 同一个 1111,按 4 位无符号数解释是 15,按 4 位补码解释是 −1。因此,同一个 F 可以有不同的数值含义,还要结合状态标志判断本次运算。
四个状态标志
| 标志 |
含义 |
如何判断 |
| ZF(Zero Flag,零标志) |
结果是否为零 |
F=0 时为 1 |
| SF(Sign Flag,符号标志) |
结果的最高位 |
等于 F 的最高位 |
| CF(Carry Flag,进位标志) |
无符号加法的进位、无符号减法的借位 |
加法看 Cout;减法按本文教材约定看 Cout |
| OF(Overflow Flag,溢出标志) |
有符号补码运算是否超出表示范围 |
按操作数与结果的符号判断 |
ZF 与 SF
F=0000 时,ZF 为 1;例如计算 X−Y 得到零,可据此判断两个 n 位操作数相等。
SF 直接复制 F 的最高位。例如 F=1110 时,SF 为 1。但 SF 不能单独说明真实计算结果是否为负数:若 OF 为 1,保留下来的符号位可能已因溢出而变号。
CF:无符号进位或借位
加法产生最高位进位时,CF=Cout=1。例如 4 位无符号数 15+1 得到 10000,超出无符号范围 0∼15,因此 CF 为 1。
减法在本电路中通过 X+Y+1 实现。此时 Cout=1 表示无符号数 X≥Y,没有借位;Cout=0 表示 X<Y,发生借位。按本文教材的 CF 约定:
CF={Cout,Cout,Sub=0,Sub=1.
因此,上面的 5−3 有 Cout=1、CF=0;而 4 位无符号数 3−5 算得 F=1110、Cout=0、CF=1,表示发生借位。
OF:有符号溢出
OF 判断真实结果是否超出 n 位补码范围。例如 4 位补码只能表示 −8∼7。计算 7+3 得到 F=1010,它按补码解释为 −6,但真实结果 10 超过上限,所以 OF=1。
符号判断规则是:同号相加,结果变号则溢出;异号相减,结果与被减数变号则溢出。 也可以比较进入与离开符号位的两次进位:不同则 OF 为 1。
CF 与 OF 可以不同
| 4 位运算 |
F |
CF |
OF |
原因 |
| 1111+0001 |
0000 |
1 |
0 |
无符号数 15+1 超出范围;补码 −1+1=0 正常 |
| 0111+0011 |
1010 |
0 |
1 |
无符号数 7+3=10 正常;补码 7+3=10 超出范围 |
记住: CF 反映无符号运算的进位或借位,OF 反映有符号补码运算的溢出;二者要分别判断。
用减法比较大小
比较两个相同位数的数 A 和 B 时,先计算 A−B,再根据数的解释方式读取相应标志。无符号数主要看 ZF、CF;有符号补码数主要看 ZF、SF、OF。
无符号数比较
减法中,ZF 为 1 表示结果为零;按本文的 CF 约定,CF 为 1 表示发生借位,即 A<B。因此:
| 条件 |
关系 |
| ZF=1 |
A=B |
| ZF=0 且 CF=0 |
A>B |
| CF=1 |
A<B |
例如,用 3 位无符号数计算 000−001,保留的结果为 111:结果非零,且减法发生借位,所以 ZF=0、CF=1,判断 0<1。这里不能把 111 按无符号数读成 7 后直接比较。
有符号数比较
若把 A、B 当作补码有符号数,发生溢出时,结果符号位 SF 可能与真实差值的正负相反。用 SF⊕OF 修正符号,再结合 ZF 判断:
| 条件 |
关系 |
| ZF=1 |
A=B |
| ZF=0 且 SF=OF |
A>B |
| ZF=0 且 SF=OF |
A<B |
例如,3 位补码中 011=+3、101=−3:
- +3−(−3) 的真实差值为 +6,超出 −4∼3 的范围;保留结果为 110,故 ZF=0、SF=1、OF=1。由于 SF=OF,判断 +3>−3。
- −3−(+3) 的真实差值为 −6,同样溢出;保留结果为 010,故 ZF=0、SF=0、OF=1。由于 SF=OF,判断 −3<+3。
对照记忆: 无符号比较看 ZF、CF;有符号比较看 ZF、SF⊕OF。
其实我有点懵逼,
之后还得再多看几遍。
出生时早知道智力分配多些点数了😇。
