Appearance
补码加减运算与溢出判别
2026 大纲 二(二)2 加/减运算:「补码加/减运算器,标志位的生成。」大纲把「标志位的生成」与运算器并列写出,是因为条件转移指令的判断条件全部建立在这四个标志上——不生成标志,加法器就只是一个算数值的部件。
加法器的物理行为,恰好就是补码要求的模运算
补码加减法的三个公式很短:
真正值得想清楚的是它们为什么不需要额外的硬件配合:
🔴 "符号位一起参加运算"和"最高位进位直接丢弃"这两条,其实是同一件事。 一个
位加法器天然就是模 的加法器——它只有 根输出线,最高位的进位无处可去、自动丢掉,而丢掉的正好是 。加法器的物理行为恰好就是补码要求的模运算,不是两条要背的规则。
对照一下就知道原码为什么不行:原码的符号位只是一个标签,不带数值权重,送进加法器一起算会得出毫无意义的结果。
🔴 机器里没有独立的减法器。 "末位加 1"也不需要额外做一次加法——加法器最低位本来就有一个进位输入
,把它置成 1 就等于免费加了 1。于是 时算 、 时算 :一个控制信号、一套加法器、两种运算。
手算求补时有条捷径:从最低位往高位找到第一个 1,该位及其右侧全部不变,左侧全部取反(含符号位)。它与"全部取反加 1"完全等价——加 1 的进位会一路传到第一个 1 为止。
交互可视化
一、加法与减法共用一套加法器
补码的定义本身就是一个模运算:
教材以定点整数按
取模、定点小数按 取模两种形式给出同一条公式,本质相同,只是小数点约定的位置不同。
减法的问题转成:怎么从
| 器件 | 作用 |
|---|---|
| 一排反相器 + 二选一多路器 | |
| 一根从 |
这就是为什么在任何一张运算器框图里都找不到独立的减法器,也是后面乘法器、除法器里的 ALU「只需支持加和减两种运算」的由来。
二、溢出的两个方向与三种判别方法
溢出指运算结果超出了
判溢出之前先记住一条能省掉一半工作量的前提:
🔴 只有同号数相加才可能溢出。 异号两数相加,结果的绝对值不会超过较大的那个,必然落在范围内。⚠️ 做减法时"同号"要看实际送进加法器的那两个数(被减数与求补之后的减数)——原式里的异号,到这里已经变成同号了。
三种判别方法常被并列成三条独立规则,其实是同一个判据在电路的不同位置被读出来:
- 符号位比较法:
,读的是三个符号位; - 进位判别法:
,读的是两个进位; - 双符号位法:读的是结果的两位符号位。
硬件更爱进位判别法——一个异或门就够,而且不必等和数产生。
双符号位(变形补码)的读法:00 正、无溢出;11 负、无溢出;01 正溢出;10 负溢出。
🔴 不论是否溢出,高位那个符号位永远是真正的符号。 ⚠️ 另外双符号位不进存储器——正确的数两位符号位必然相同,存两份是浪费;它只在送进加法器时把那一位复制成两位。
🔴 进位丢弃
溢出。 进位丢弃是模 运算的正常行为,每次运算都可能发生,本身不代表任何错误。判溢出必须同时看 和 ,只看一个 什么也说明不了。
⚠️ 最后交代下标约定:本站统一
三种方法为什么恒等:进位判别法与符号位比较法的逐情形推导,以及双符号位法的恒等式(想弄清它们不是三件事、或不放心双符号位法的原理时展开)
进位判别法与符号位比较法为什么等价。 符号位上做的是一次全加:
- 两数都是正数(
):符号位是 ,必然不产生进位, ;而 。于是"和为负" 。 - 两数都是负数(
):符号位是 ,必然产生进位, ;而 。于是"和为正" 。 - 两数异号:符号位是
,进位直接穿过去, ,异或恒为 0——与"异号不溢出"完全吻合。
双符号位法就是进位判别法的"硬件版"。 把每个操作数扩成两位符号位(正数补 00、负数补 11),两位符号位连同数值位一起参加运算,模数从
两式异或,
"两位符号位不同"与"两个进位不同"是恒等式,不是巧合。 双符号位法所做的,无非是多花一位加法器硬件,把
两组数据上把三种方法各跑一遍(想看"同一个电路的三个读出位置"具体怎么对上,或想确认进位丢弃不等于溢出时展开)
(一)
01100100 (+100)
+ 00111000 (+56)
----------
10011100- 符号位比较法:
, ——同号相加得异号,溢出。 - 进位判别法:最高数值位向符号位有进位
;符号位 不产生进位, 。 ,溢出。 - 双符号位法:
001100100 + 000111000 = 010011100,符号位01,正溢出;高位符号位为 0,说明真正的符号是正。
三条路径读的是同一个电路的三个不同位置。真值
(二)
10110101 (-75)
+ 11001011 (-53)
----------
1 10000000 ← 最高位进位丢弃- 符号位比较法:同为负,结果符号位也是 1——无溢出。
- 进位判别法:
, , ,无溢出。 - 双符号位法:
110110101 + 111001011 = 110000000(丢弃最高进位),符号位11,无溢出。
这一组最高位有进位(被丢弃)却没有溢出——进位丢弃与溢出是两件事。结果 10000000
三、标志位的生成
设
| 标志 | 表达式 | 对谁有意义 |
|---|---|---|
| ZF(零标志) | 两者都有 | |
| SF(符号标志) | 只对带符号数 | |
| OF(溢出标志) | 只对带符号数 | |
| CF(进位/借位标志) | 只对无符号数 |
教材把 CF 写成
。因为 就接在 上,两式是同一式子。
8 位无符号减法验算 CF 的取反规则:
| 运算 | 结果 | CF | 含义 | |
|---|---|---|---|---|
50H − 30H | 20H | 1 | 0 | 够减,无借位 |
30H − 50H | E0H | 0 | 1 | 不够减,有借位 |
🔴 CF 不能直接取
。 减法在硬件上是 ,够减时最高位反而会产生进位;而无符号减法里 CF 的语义是"借位",够减时不该置位。所以加法取 、减法取 ,合起来就是 。
🔴 减法的 OF 也必须单独推,不能照抄加法版:
读作「
与 异号,且差与 异号」。把加法版的同号项照搬到减法上,8 位下有一半的输入组合会判错。
🔴 CF 与 OF 可以任意组合,因为它们判的根本不是同一件事:
01100100+00111000得 CF 0 / OF 1;11111111+00000001得 CF 1 / OF 0;10000000+10000000得 CF 1 / OF 1。无符号比较用 CF,带符号比较用 OF 和 SF。
四个标志存入标志寄存器 FR,其输出接到控制器 CU 的输入端——条件转移指令就是读这些位来决定跳不跳。例如无符号数的"大于"用
考点速记
- 补码加法能让符号位参与运算、最高位进位直接丢弃,是因为加法器本身就是模
加法器;减法通过 实现,"末位加 1"由最低位进位输入 免费提供,机器里没有独立的减法器。 - 只有同号数相加才可能溢出(减法看被减数与求补后的减数);三种判别方法本质相同,由
与恒等式 相互推出;进位丢弃 溢出。 - 四个标志
中,CF 管无符号、OF 管带符号,同一次运算两者可以取值不同;减法的 CF 要取 的反,减法的 OF 表达式也必须单独推。
这一节在真题里被考过的形式(下方「真题练习」里属于本篇的那几道):
- 给两个数与一个运算,问会不会溢出:先看送进加法器的那两个数是否同号——异号直接判不溢出,同号再看结果符号有没有反过来。
、 这类题里, -x-y才是同号相加的那一个。 - 给两个补码机器数,问
的值与 OF:按 实做一遍,用 判 OF。⚠️ 别用加法的同号判据去套减法。 - 给一组数据下的 OF 与 CF,问换一组数据后 OF 与 CF 是多少:这类题考的正是两者互相独立——把新数据实做一遍,分别用各自的判据读出来,不能从旧结果推。
- 问某条件转移指令的转移条件是什么标志组合:先分清是无符号比较还是带符号比较——无符号用 CF 与 ZF(如"大于"是
),带符号用 SF、OF 与 ZF。这一步分错,四个选项都对不上。
易错:把进位丢弃当成溢出。要同时看
与 。
易错:做减法时按原式的符号判"同号"。要看求补之后送进加法器的那两个数。
易错:减法直接取
当 CF。够减时反而有进位,要取反。
易错:用 CF 判带符号溢出、或用 OF 判无符号进位。两者各管一边。
教材出处
- 一位符号位判溢出、"符号位进位与最高有效位进位异或"判据:唐朔飞《计算机组成原理》第 3 版 §6.2 定点运算,印刷页 p239–p240
- 变形补码(模 4 补码)定义、"两位符号位不同即溢出、高位符号位永远代表真正的符号"、双符号位只在加法器中展开:同书印刷页 p240–p241
- 补码加减运算基本公式与"求补"减法:同书印刷页 p237
- 带标志加法器的四个标志表达式(
、 、 ):袁春风《计算机组成与系统结构》第 3 版 §3.2.3 带标志加法器,印刷页 p58 - 补码加减统一用加法处理、
同时接反相器与最低位进位输入的电路(图 3.9):同书 §3.3.1 补码加减运算,印刷页 p60 - 四个标志各自对谁有意义、
的推导、两种溢出判别逻辑表达式并列给出:同书印刷页 p61
相关知识
算术逻辑单元(ALU)|定点数编码的转换与书写|真值与机器数:四种编码的定义|乘除运算的基本原理与实现结构