精简版 · 小杯2026-08 冻结,已停止更新(发布前修订了 4 处已知错误)。后续勘误与新增内容只在正式版。看正式版(中杯)→
Skip to content

补码加减运算与溢出检测 ​

大纲定位 ​

二(二)2 加/减运算:补码加/减运算器,标志位的生成

要求:会做补码加减、会判溢出(三种方法任一)、会写出 OF/SF/ZF/CF 四个标志的生成式。大纲把"标志位的生成"单列出来,说明它不是附带知识——条件转移指令的判断条件全建立在这四个标志上。

加法器本身的电路结构见 ALU 与加法器。

考情分析 ​

补码加减运算与溢出判断在选择题和大题里都出现过。三种溢出判断方法(单符号位法、双符号位法/变形补码、进位法)都要掌握。

补码加减法规则 ​

补码加法 ​

[A+B]补=[A]补+[B]补(mod2n)

即两数补码直接相加,符号位参与运算,最高位(符号位)的进位丢弃。

补码减法 ​

[A−B]补=[A]补+[−B]补

减法转化为加法,关键是求 [−B]补:将 [B]补 连同符号位一起取反加 1(即求补操作)。

求补操作的快速方法:从最低位开始,找到第一个 1,保持该位及其右侧所有位不变,左侧所有位(包括符号位)取反。

例:[B]补=10110100,求 [−B]补

最低位的 1 在第 3 位(从右数),保留右侧 100,左侧 10110 → 01001

[−B]补=01001100

溢出的本质 ​

溢出指运算结果超出了机器数所能表示的范围。

对于 n 位有符号补码:

  • 正溢出(上溢):结果 >2n−1−1,两个正数相加但结果变成负数
  • 负溢出(下溢):结果 <−2n−1,两个负数相加但结果变成正数

TIP

同符号数相加才可能溢出,异符号数相加不会溢出。

三种溢出判断方法 ​

方法一:单符号位法 ​

观察操作数符号位和结果符号位:

V=A符⋅B符⋅S符―+A符―⋅B符―⋅S符

用语言描述:

  • 两个正数相加,结果为负 → 正溢出
  • 两个负数相加,结果为正 → 负溢出
  • 其他情况不溢出
A 符号位B 符号位S 符号位溢出判断
000无溢出
001正溢出
010无溢出
011无溢出
100无溢出
101无溢出
110负溢出
111无溢出

方法二:双符号位法(变形补码/模 4 补码) ​

将每个操作数扩展为双符号位:

  • 正数:补两个 0,如 +X → 00X
  • 负数:补两个 1,如 −X → 11X

运算后观察结果的两位符号位:

双符号位结果含义
00结果为正,无溢出
11结果为负,无溢出
01正溢出(结果应为正但超出范围)
10负溢出(结果应为负但超出范围)

口诀:双符号位相同 → 无溢出;不同 → 溢出(高位符号位是正确符号)。

方法三:进位法 ​

设机器字长 n 位,加法器的进位从低到高依次记为 C1,C2,…,Cn(C0 是最低位的进位输入)。溢出只看最高两级进位:

  • Cn:符号位产生的进位(进位输出)
  • Cn−1:最高数值位向符号位的进位
OF=Cn−1⊕Cn
  • Cn−1≠Cn → 溢出
  • Cn−1=Cn → 无溢出

下标别记反

本站 ALU 与运算部件 一篇用的是同一套约定:C0 是进位输入,不是进位输出。有些资料把符号位的进位记作 C0、数值位的记作 C1,公式写成 V=C0⊕C1——含义相同但下标相反,混用会把判断做反。做题时以题面给的图和标注为准。

标志位的生成 ​

大纲二(二)2 的原文是「补码加/减运算器,标志位的生成」——运算器和标志位是同一条要求的两半。综合应用题里这部分是按逻辑表达式给分的,光会中文描述不够。

补码加减运算器长什么样 ​

一个 n 位加法器就能同时做加和减,靠的是两件事:把 Y 送进一排反相器再经二选一多路器(Sub=1 时选反相后的 Y―),同时把控制信号 Sub 接到最低位的进位输入 C0。于是

Sub=0: X+YSub=1: X+Y―+1=X−Y

这正是「减法转加法」在电路上的落地——不需要单独的减法器。

四个标志的表达式 ​

设 n 位运算结果为 F,Cn 是符号位产生的进位(即进位输出 Cout),Cn−1 是最高数值位向符号位的进位:

标志表达式对谁有意义
ZF(零标志)ZF=1⟺F=0两者都有
SF(符号标志)SF=Fn−1(结果最高位)只对带符号数
OF(溢出标志)OF=Cn⊕Cn−1只对带符号数
CF(进位/借位标志)CF=Sub⊕Cout只对无符号数

CF 这一条最容易写错 ​

减法在硬件上是 X+Y―+1,最高位常常会产生进位。若直接令 CF=Cout 就错了——减法的 CF 语义是「借位」,够减时不该置位。

加法(Sub=0): CF=Cout减法(Sub=1): CF=Cout―

合起来就是 CF=Sub⊕Cout。验算一下 8 位无符号减法:

运算结果CoutCF含义
50H − 30H20H10够减,无借位
30H − 50HE0H01不够减,有借位

OF 还有一个等价的符号位形式 ​

除了 Cn⊕Cn−1,标答也常用只含符号位的形式(A、B 为两个操作数):

OF加=An−1Bn−1Fn−1―+An−1―Bn−1―Fn−1

读作「两个加数同号,但结果与它们异号」。两式在 8 位下穷举 65536 种组合完全等价。

减法版必须单独推,不能照抄加法版。A−B 相当于 A+(−B),把 B 翻号后代入:

OF减=An−1Bn−1―Fn−1―+An−1―Bn−1Fn−1

读作「A、B 异号,且结果与 A 异号」。把减法的 OF 写成与加法同形式(同号项)是明确要扣分的。

标志位往哪去 ​

四个标志存进标志寄存器 FR,它的输出连到控制器 CU 的输入端——条件转移指令就是靠读这些位决定跳不跳。例如无符号数的「大于」判断用的是 CF+ZF―(既没借位、又不相等)。

一句话记法

CF 管无符号,OF 管带符号,同一次运算完全可能 CF=1 而 OF=0(或反过来)——它们判的根本不是同一件事。

交互可视化 ​

加载可视化中...
加载可视化中...
加载可视化中...

典型例题 ​

例题 1:8 位补码,计算 [A]补=01100100,[B]补=00111000,求 [A+B]补 并判断是否溢出。

  01100100  (+100)
+ 00111000  (+56)
----------
  10011100

结果符号位为 1,但两个正数相加结果为负 → 正溢出。

双符号位验证(8位字长扩展为9位:2位符号 + 7位数值):

  001100100
+ 000111000
----------
  010011100

双符号位为 01 → 确认正溢出。

例题 2:8 位补码,计算 [A]补=10110101,[B]补=11001011,求 [A+B]补。

真值:A=−75,B=−53,A+B=−128,在 8 位补码范围 [−128,127] 内。

  10110101  (-75)
+ 11001011  (-53)
----------
1 10000000  进位丢弃

结果为 10000000 = −128,无溢出。

进位法:C0=1(符号位进位),C1=1(最高数值位进符号位),V=1⊕1=0,无溢出。

例题 3:用双符号位法计算 A=−70,B=−80 的补码加法。

−70 的补码(8位):10111010,双符号位扩展为9位:110111010−80 的补码(8位):10110000,双符号位扩展为9位:110110000

  110111010
+ 110110000
----------
1 101101010  最高进位丢弃

双符号位为 10 → 负溢出(−150<−128)。

考点清单 ​

  • [ ] [A+B]补=[A]补+[B]补,符号位参与运算
  • [ ] 补码减法:[A−B]补=[A]补+[−B]补,对 [B]补 连符号位一起求补
  • [ ] 同符号数相加才可能溢出,异符号不溢出
  • [ ] 单符号位法:看操作数符号与结果符号
  • [ ] 双符号位法:00/11 无溢出,01 正溢出,10 负溢出
  • [ ] 进位法:V=C0⊕C1
  • [ ] 快速求补:找最低位 1,左侧全部取反(含符号位)

真题练习 ​