本篇笔记课程来源:王道计算机考研 计算机组成原理
上节已经介绍了一些基础知识和数字电路,本节则涉及数的表示和运算
【计算机组成原理】第二章:数据的表示和运算(下)
六、定点数移位运算
- 移位运算:通过改变各个数码位和小数点的相对位置,从而改变各数码位的位权
- 应用:可以通过移位运算快速实现特殊数值的乘法、除法
1. 逻辑移位
- 逻辑移位常用于处理无符号整数
- 逻辑左移:高位移出丢弃,低位补 0
- 每逻辑左移 r r r 位,则相当于 × 2 r ×2^r ×2r
- 溢出判定:若逻辑左移丢弃的位 = 1 =1 =1,则发生溢出(超过 n bit 无符号整数的表示范围)
- 逻辑右移:低位移出丢弃,高位补 0
- 每逻辑右移 r r r 位,相当于 ÷ 2 r ÷2^r ÷2r
- 若逻辑右移丢弃的位 = 1 =1 =1,则会丢失精度
2. 算术移位
- 算术移位常用于处理带符号整数
- 算术左移:
- 运算规则与逻辑左移一样
- 溢出判定:若算术左移前后的符号位不同,则发生溢出
- 算术右移:低位移出丢弃,高位补符号位
- 其他的和逻辑右移一样
七、加减运算
1. 定点数原码的加减
- 原码加法
被加数 + 加数 运算规则 正 + 正 绝对值做加法,结果为正,可能会溢出 负 + 负 绝对值做加法,结果为负,可能会溢出 正 + 负 绝对值大的减绝对值小的,符号同绝对值大的数 负 + 正 绝对值大的减绝对值小的,符号同绝对值大的数 - 原码减法:“减数” 符号取反,即可转为加法
2. 定点数补码的加减
- 对于补码来说,无论是加法还是减法,最后都会转变成加法,有加法器实现运算,符号位也参与运算
机器字长为 8 位,A = 15,B = -24,求 [A+B]补 和 [A-B]补
- [A]补 = 0,0001111,[B]补 = 1,1101000
- [A+B]补 = [A]补 + [B]补 = 1,1110111
- [A-B]补 = [A]补 + [-B]补 = 0,0001111 + 0,0011000 = 0,0100111
- 补码转原码更快的方法:最右边的 1 及其右边同原码,最右边的 1 的左边同反码(找个例子试一遍就知道了)
3. 有符号数的溢出判断
- 上溢:只有 “正数 + 正数” 才会上溢,结果为负数
- 下溢:只有 “负数 + 负数” 才会下溢,结果为正数
- 单符号位补码又称 模 2 补码,双符号位补码又称 模 4 补码
- 双符号位在存储时只存储 1 个符号位,运算时会复制一个符号位
- 方法一:
- 采用一位符号位,两个加数同号,运算结果变号,则有溢出
- 记 A A A 的符号为 A S A_S AS, B B B 的符号为 B S B_S BS,运算结果 S S S 的符号为 S S S_S SS,则溢出逻辑表达式为 V = A S B S S S ‾ + A S ‾ B S ‾ S S = { 0 , 无溢出 1 , 有溢出 V=A_SB_S \overline{S_S} + \overline{A_S} \overline{B_S} S_S= \begin{cases} 0, & 无溢出 \\ 1, & 有溢出 \\ \end{cases} V=ASBSSS+ASBSSS={0,1,无溢出有溢出若 V = 0 V=0 V=0 表示无溢出, V = 1 V=1 V=1 表示有溢出
- 方法二:
- 采用一位符号位,根据数据位进位情况判断溢出。若符号位的进位与最高数值位的进位不同则发生溢出
- 记符号位的进位为 C S C_S CS,最高数值位的进位为 C 1 C_1 C1,则 V = C S ⊕ C 1 = { 0 , 无溢出 1 , 有溢出 V=C_S \oplus C_1=\begin{cases} 0, & 无溢出 \\ 1, & 有溢出 \\ \end{cases} V=CS⊕C1={0,1,无溢出有溢出若 V = 0 V=0 V=0 表示无溢出, V = 1 V=1 V=1 表示有溢出
- 方法三:
- 采用双符号位,正数符号为 00,负数符号为 11,若运算结果的两个符号位不同则溢出
- 记两个符号位为 S S 1 、 S S 2 S_{S1}、S_{S2} SS1、SS2,则 V = S S 1 ⊕ S S 2 = { 0 , 无溢出 1 , 有溢出 V=S_{S1} \oplus S_{S2}=\begin{cases} 0, & 无溢出 \\ 1, & 有溢出 \\ \end{cases} V=SS1⊕SS2={0,1,无溢出有溢出若 V = 0 V=0 V=0 表示无溢出, V = 1 V=1 V=1 表示有溢出
4. 无符号数的加减
- 加法:从最低位开始,按位相加,并往更高位进位
- 减法:“被减数” 不变,“减数” 变为补数(
A-B变为A+(-B)),然后就变成了加法- “减数” 全部位按位取反,末位 +1
5. 无符号数的溢出判断
- 手算判断溢出: n n n bit 无符号整数表示范围 0 0 0 ~ 2 n − 1 2^n-1 2n−1,超出此范围则溢出
- 加法判断溢出:最高位产生的进位 = 1 =1 =1 时,发生溢出,否则未溢出。
- 减法判断溢出:减法变加法,最高位产生的进位 = 0 =0 =0 时,发生溢出,否则未溢出。
八、乘除运算
1. 无符号整数乘法
- 基本原理:逐位相乘,错位相加
- 两个 n n n bit 的无符号数的乘法,可拆解为 n n n 轮加法运算
- 根据乘数的各个 bit,决定每一轮加法运算 “+ 被乘数” 或 “+ 全 0”
- 每一轮加法运算需要与上一轮加法运算的结果 “错位相加”
- 32 位无符号数乘法运算电路结构和解释说明,接下来的运算过程基于此图

- 4 位简化版

运算过程:
- 开始:
- 被乘数、乘数分别放入寄存器 X 、 Y X、Y X、Y
- 乘积寄存器 P P P 置为 0
- 计数器 Cn \text{Cn} Cn 的初始值置为 n n n
- 进行
n
n
n 轮处理:重复
n
n
n 轮加法、移位运算,直到计数器
Cn
=
0
\text{Cn}=0
Cn=0
- 将乘数寄存器 Y 的最低位,送入 “控制逻辑” 进行判断
-
- 若 Y Y Y 的最低位为 1,则执行加法,运算结果写回 P P P,加法产生的进位保存至进位触发器 C C C
- 若 Y Y Y 的最低位为 0,则什么也不做
- 将 【 C , P , Y C,P,Y C,P,Y】视为整体,逻辑右移一位
- 计数器 Cn \text{Cn} Cn 减 1
- 结束:当计数器
Cn
=
0
\text{Cn}=0
Cn=0 时,乘法运算结束
- 用 2 n 2n 2n 位【 P , Y P,Y P,Y】暂存乘法运算结果,但最终仅保留低 n n n 位【 Y Y Y】作为最终结果,因此可能发生溢出
- 溢出判断:若丢弃的高 n n n 位【 P P P】不全为 0,说明发生溢出,并设置 OF 标志位 = 1 =1 =1
- 溢出处理:可选择忽略乘法溢出。或选择在乘法指令之后执行一条 “溢出自陷指令”(如 x86 的 INTO Interrupt on Overflow 指令),当 OF = 1 时会触发 “异常处理程序” 来处理溢出
2. 带符号整数乘法
- 与无符号整数乘法电路的不同
- 可能进行加法、减法
- 控制逻辑根据 2 bit( Y Y Y 的最低位、辅助位)决定本轮该如何处理
- 低位增加一个 “辅助位”
- 不保存最高位产生的进位信息
- 32 位带符号数乘法运算电路结构和解释说明,接下来的运算过程基于此图

- 4 位简化版

运算过程
前情提要:
- 带符号数(补码)乘法,符号位参与运算
- 当被乘数、乘数种有一个全为 0 时,结果直接得 0,不需要在进行后续的运算步骤
- 开始:
- 将被乘数、乘数分别放入寄存器 X 、 Y X、Y X、Y
- 乘积寄存器 P P P 置为 0,“辅助位” 置为 0(辅助位就是图中的黄色块)
- 计数器 Cn \text{Cn} Cn 的初始值置为 n n n
- 进行
n
n
n 轮处理:重复
n
n
n 轮加 / 减法、移位运算,直到计数器
Cn
=
0
\text{Cn}=0
Cn=0
- 将乘数寄存器 Y Y Y 的最低位、辅助位,2 bit 送入 “控制逻辑” 进行判断
- 根据寄存器
Y
Y
Y 的最低位、辅助位,决定是 “+[x]补”、“-[x]补”、“+0”(记忆技巧:辅助位 -
Y
Y
Y最低位)
寄存器 Y Y Y 最低位 辅助位 本轮操作 0 0 +0 0 1 +[x]补 1 0 -[x]补 1 1 +0 - 将【 P 、 Y 、辅助位 P、Y、辅助位 P、Y、辅助位】视为整体,算数右移一位
- 计数器 Cn \text{Cn} Cn 减 1
- 结束:当计数器
Cn
=
0
\text{Cn}=0
Cn=0 时,乘法运算结束
- 用 2 n 2n 2n 位【 P , Y P,Y P,Y】暂存乘法运算结果,但最终仅保留低 n n n 位【 Y Y Y】作为最终结果,因此可能发生溢出
- 溢出判断:若 2 n 2n 2n 位的高 n + 1 n+1 n+1 位不完全相同,说明发生溢出,并设置 OF 标志位 = 1 =1 =1
- 溢出处理与无符号整数乘法一样
3. 实现乘法运算的方式
- 计算机实现乘法运算的三种方式:
- 由 ALU、移位器、寄存器、控制逻辑组成的乘法电路(就是上面说的电路)
- 该电路若实现 n n n bit 无符号数相乘,至少需要 n n n 个时钟
- 改进方案:可以实现 “两位乘法”,每轮处理乘数寄存器 Y Y Y 的末尾 2 bit,此时仅需 2 n \frac{2}{n} n2 个时钟即可完成运算
- 阵列乘法器
- 特点:可以在 1 个时钟内完成乘法运算
-
4
×
4
4×4
4×4 位阵列乘法器示例图

- 阵列乘法器是快速乘法器种的一种。很多快速乘法器都可以在 1 个时钟内完成乘法运算
- 由逻辑运算(位运算、移位运算)、加 / 减运算等效实现乘法
- 优点:在没有乘法运算电路、不支持乘法指令的计算机中,也可以等效实现乘法效果
- 缺点:运算速度很慢(在非流水线计算机中,每条指令的执行都至少需要 1 个时钟)
- 由 ALU、移位器、寄存器、控制逻辑组成的乘法电路(就是上面说的电路)
4. 无符号整数除法
- 除法手算方法:逐位上商,错位相减
- 二进制上商规则:商 × 除数的值,要尽可能接近 “中间余数”,但又不能大于中间余数。如果中间余数 ≥ 除数,则上商 1,否则上商 0
- 余数的数学定义: 被除数 = 商 × 除数 + 余数 被除数=商×除数+余数 被除数=商×除数+余数
- 除法器支持
2
n
bit
÷
n
bit
2n \text{ bit} ÷n \text{ bit}
2n bit÷n bit,最终得到
n
bit
n \text{ bit}
n bit 商、
n
bit
n \text{ bit}
n bit 余数
- 被除数位不足 2 n 2n 2n,需要位扩展(高位补 0)至 2 n 2n 2n
- 无符号整数的双精度除法( 2 n ÷ n 2n÷n 2n÷n)可能发生 “商溢出”;
- 无符号整数的单精度除法( n ÷ n n÷n n÷n)不可能发生 “商溢出”
- 32 位无符号数除法运算电路结构和说明

- 4 位简化版

运算过程:
- 开始:
- 正常情况:将数据放入寄存器:
- 除数放入寄存器 Y Y Y
- 被除数放入寄存器【 R 、 Q R、Q R、Q】并完成零扩展
- 计数器 Cn \text{Cn} Cn 的初始值置为 n n n
- 特殊情况检查:
- 如果除数为 0,发生 “除数为0” 异常,停止除法运算,调出操作系统的异常处理程序
- 如果 ∣ 被除数 ∣ < ∣ 除数 ∣ |被除数|<|除数| ∣被除数∣<∣除数∣,则商 = 0,余数 = 被除数,除法器不必再执行
- 正常情况:将数据放入寄存器:
- 进行
1
+
n
1+n
1+n 轮处理(计算
1
+
n
1+n
1+n 位商)
- 上商规则:如果【 R R R】-【 Y Y Y】≥ 0,则上商 1,否则上商 0
- 第一轮:特殊处理,商溢出判断
- 直接上商,若第一位商 = 1,发生 “商溢出” 异常,停止除法运算
- 直接上手,若第一位商 = 0,说明不会发生 “商溢出”,不必保存这位商,也不让 Cn − − \text{Cn}-- Cn−−,除法运算继续
第一位商不保存,仅用于商溢出判断
- 其余
n
n
n 轮处理
- 先左移,空出的位用于上商
- 上商,背后的过程可能会进行加法 / 减法
- 比如上商是 R − Y R-Y R−Y,如果差 < 0,需要恢复余数 R − Y + Y R-Y+Y R−Y+Y
- 计数器 Cn \text{Cn} Cn 减 1
- 结束:当计数器
Cn
=
0
\text{Cn}=0
Cn=0 时,除法运算结束
- n bit n \text{ bit} n bit 寄存器【 R R R】保存余数, n bit n \text{ bit} n bit 寄存器【 Q Q Q】保存商
在 x86 中,除数为 0、商溢出 都属于 “除法错异常”(Divide Error Exception),也可简译为 “除法异常”
九、浮点数的表示
1. 科学计数法
- 科学技术法由 符号、尾数、基数、阶码组成
- 符号:决定数值的正负性
- 尾数:影响数值的精度。尾数的位数越多,精度越高
- 阶码:反映小数点的实际位置
- 基数: K K K 进制通常默认基数为 K K K
- 规格化:确保尾数的最高位非 0 位数刚好在小数点之前

- 二进制科学计数法:
- 如 − 110.11 ⟹ − 1.1011 × 2 2 -110.11\Longrightarrow -1.1011×2^2 −110.11⟹−1.1011×22
2. IEEE 754
- IEEE 754 —— 由 IEEE 制定的二进制浮点数算术标准,规定了在计算机内部,如何使用二进制表示和运算浮点数。
- 如 C 语言 float 型(32 bit,单精度浮点型)、double 型(64 bit,双精度浮点型)、long double(80 bit,扩展精度浮点型)
- 其他:16 bit 半精度浮点型、128 bit 四倍精度浮点型
- float 单精度浮点型的存储
- 占 32 bit = 1 bit 符号 + 8 bit 阶码 + 23 bit 尾数

- 符号的存储:0 正 1 负
- 阶码的存储:用移码表示,规定偏置值为 127(28-1 - 1)
将十进制真值转换为偏置值为 M M M 的移码
- 将十进制真值 + 偏置值
- 按 “无符号整数” 规则转换为指定位数
例: 2 + 127 = 129 ⟹ 10000001 2+127=129 \Longrightarrow 10000001 2+127=129⟹10000001
- 尾数的存储:规定小数点位置在 23 bit 之前。默认存储规格化尾数,小数点前的 1 省略(隐含,因此实际可表示 24 bit)
- 基数不用专门存储,规定基数为 2 即可
- 占 32 bit = 1 bit 符号 + 8 bit 阶码 + 23 bit 尾数
- double 双精度浮点型的存储
- 占 64 bit = 1 bit 符号 + 11 bit 阶码 + 52 bit 尾数

- 符号、尾数、基数与单精度浮点型一样
- 阶码:规定偏置值为 1023(211-1 - 1)
- 占 64 bit = 1 bit 符号 + 11 bit 阶码 + 52 bit 尾数
3. 表示范围
- IEEE 754 标志规定:
- 仅当阶码不全为 0、也不全为 1 时,表示这是一个 “规格化浮点数”
- 阶码全为 0、全为 1 留作特殊用途,需要按照特殊的方式取解读真值
- 规格化(单精度)浮点数的表示范围
- 规格化浮点数的阶码不能全为 0 或全为 1,因此阶码取值范围是 1 ~ 254,减掉偏置值 127 后真值取值范围是 -126 ~ 127
- 尾数的小数点前隐含 1
说明 符, 阶, 尾 二进制 十进制 正数最小 0, 00000001, 00…00 + 1.0 × 2 − 126 +1.0×2^{-126} +1.0×2−126 + 1.0 × 2 − 126 +1.0×2^{-126} +1.0×2−126 正数最大 0, 11111110, 11…11 + 1.11...11 × 2 127 +1.11...11×2^{127} +1.11...11×2127 + ( 2 − 2 − 23 ) × 2 127 +(2-2^{-23})×2^{127} +(2−2−23)×2127 负数最小 1, 11111110, 11…11 − 1.11...11 × 2 127 -1.11...11×2^{127} −1.11...11×2127 − ( 2 − 2 − 23 ) × 2 127 -(2-2^{-23})×2^{127} −(2−2−23)×2127 负数最大 1, 00000001, 00…00 − 1.0 × 2 − 126 -1.0×2^{-126} −1.0×2−126 − 1.0 × 2 − 126 -1.0×2^{-126} −1.0×2−126
- 非规格化(单精度)浮点数表示范围
- 非规格化的阶码全 0、尾数不全为 0。因此阶码真值 = 1 - 偏置值
- 尾数的小数点前隐含 0
说明 符, 阶, 尾 二进制 十进制 正数最小 0, 00000000, 00…01 + 0.00...01 × 2 − 126 +0.00...01×2^{-126} +0.00...01×2−126 + 2 − 23 × 2 − 126 = + 2 − 149 +2^{-23}×2^{-126}=+2^{-149} +2−23×2−126=+2−149 正数最大 0, 00000000, 11…11 + 0.11..11 × 2 − 126 +0.11..11×2^{-126} +0.11..11×2−126 + ( 1 − 2 − 23 ) × 2 − 126 = + ( 2 − 126 − 2 − 149 ) +(1-2^{-23})×2^{-126}=+(2^{-126}-2^{-149}) +(1−2−23)×2−126=+(2−126−2−149) 负数最小 1, 00000000, 11…11 − 0.11..11 × 2 − 126 -0.11..11×2^{-126} −0.11..11×2−126 − ( 1 − 2 − 23 ) × 2 − 126 = − ( 2 − 126 − 2 − 149 ) -(1-2^{-23})×2^{-126}=-(2^{-126}-2^{-149}) −(1−2−23)×2−126=−(2−126−2−149) 负数最大 1, 00000000, 00…01 − 0.00...01 × 2 − 126 -0.00...01×2^{-126} −0.00...01×2−126 − 2 − 23 × 2 − 126 = − 2 − 149 -2^{-23}×2^{-126}=-2^{-149} −2−23×2−126=−2−149
4. 特殊状态
- (单精度)特殊状态
值的类型 符号 阶码 尾数 值 例子 正零 0 全 0 全 0 +0 正下溢 负零 1 全 0 全 0 -0 负下溢 非规格化正数 0 全 0 不全 0 0. 尾数 × 2 − 126 0.尾数×2^{-126} 0.尾数×2−126 00200000 H = + 2 − 128 00200000\text{H}=+2^{-128} 00200000H=+2−128 非规格化负数 1 全 0 不全 0 − 0. 尾数 × 2 − 126 -0.尾数×2^{-126} −0.尾数×2−126 80200000 H = − 2 − 128 80200000\text{H}=-2^{-128} 80200000H=−2−128 正无穷 0 全 1 全 0 + ∞ +∞ +∞ 正数除以 0、正上溢 负无穷 1 全 1 全 0 − ∞ -∞ −∞ 负数除以 0、负上溢 无定义数(非数) 0、1 全 1 不全 0 NaN 零除以零、负数开根号等 - 浮点数的上溢(Overflow)
- 运算结果大于最大规格化正数时称为正上溢;小于绝对值最大的规格化负数时称为负上溢
- 正上溢、负上溢统称为上溢,也会翻译成溢出
- 浮点数上溢的处理:
- IEEE 754 规定,默认不响应浮点数溢出异常,不中断程序,除非程序员手动开启此类异常响应
- 浮点数运算部件将运算结果设为 + ∞ +∞ +∞ 或 − ∞ -∞ −∞
- 设置浮点数溢出异常标志位(如 x86 会将浮点运算单元 FPU 的 OE 标志位 Overflow Exception 置为 1)
- 浮点数的下溢(Underflow)
- 若浮点数运算结果在 0 至绝对值最小的规格化正数之间时称为正下溢,在 0 至绝对值最小规格化负数之间时称为负下溢
- 正下溢、负下溢统称为下溢
- 浮点数下溢的处理:
- IEEE 754 规定,默认不响应浮点数溢出异常,不中断程序,除非程序员手动开启此类异常响应
- 若结果落入非规格化区间,则用非规格化浮点数存储;若结果太小(真值逼近于 0)则按机器零存储
- 若下溢至机器零,设置浮点数下溢异常标志位(如 x86 会将 FPU 的 UE 标志位 Underflow Exception 置为 1)
十、数据的存储和排列
1. 大小端模式
- 最高有效字节(MSB):一个数值的最左边字节
- 最低有效字节(LSB):一个数值的最右边字节
- 大端模式:
- 把最高的有效字节存到更低地址部分,最低有效字节存在较高地址部分。
- 优点:便于人类阅读
- 小端模式:
- 和大端模式反过来
- 优点:便于机器处理
如 4 字节 int:01 23 45 67 H
- 最高有效字节:01
- 最低有效字节:67
- 大端模式:01 23 45 67
- 小端模式:67 45 23 01
2. 边界对齐
- 现代计算机通常是按字节编址,即每个字节对应 1 个地址。通常也支持按字、按半字、按字节寻址

- 不管是按字还是按半字寻址,最终都要转换为字节地址。字、半字、字节之间的转换是逻辑移位
假设存储字长 32 位,1 字 = 32 bit,半字 = 16 bit,1 字节 = 8 bit
- 字节地址 = 字地址 × 22(字地址逻辑左移 2 位得到字节地址)
- 每次访存只能读 / 写 1个字
十一、数的比较
- 部分比较和转移指令:
- CMP 指令:Compare 比较
- JMP 指令:jump 无条件转移
- JE 指令:jump if equal 相等则跳转
- JG 指令:jump if greater 大于则跳转
- 数的比较硬件步骤:
- 通过 “cmp 指令” 比较 a 和 b(
cmp a, b),实质上是用 a − b a-b a−b - 相减的结果信息会记录在程序状态字寄存器(PSW,也称标志寄存器)中
- 进位 / 借位标志 CF、零标志 ZF、符号标志 SF、溢出标志 OF
- 根据 PSW 的某几个标志位进行条件判断,来决定是否转移
je 2:表示 a = b a=b a=b 时跳转到 2jg 2:表示 a > b a>b a>b 时跳转到 2jump 2:不管 PSW 的各种标志位直接跳转到 2
- 通过 “cmp 指令” 比较 a 和 b(

&spm=1001.2101.3001.5002&articleId=149813741&d=1&t=3&u=e4f6484a6d6d4c1082b99f0749f3acc8)
3899

被折叠的 条评论
为什么被折叠?



