【计算机组成原理】第二章:数据的表示和运算(下)

本篇笔记课程来源:王道计算机考研 计算机组成原理

上节已经介绍了一些基础知识和数字电路,本节则涉及数的表示和运算

接上节:【计算机组成原理】第二章:数据的表示和运算(上)

六、定点数移位运算

  • 移位运算:通过改变各个数码位和小数点的相对位置,从而改变各数码位的位权
  • 应用:可以通过移位运算快速实现特殊数值的乘法、除法

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 个符号位,运算时会复制一个符号位

  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 表示有溢出
  2. 方法二:
    • 采用一位符号位,根据数据位进位情况判断溢出。若符号位的进位与最高数值位的进位不同则发生溢出
    • 记符号位的进位为 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=CSC1={0,1,无溢出有溢出 V = 0 V=0 V=0 表示无溢出, V = 1 V=1 V=1 表示有溢出
  3. 方法三:
    • 采用双符号位,正数符号为 00,负数符号为 11,若运算结果的两个符号位不同则溢出
    • 记两个符号位为 S S 1 、 S S 2 S_{S1}、S_{S2} SS1SS2,则 V = S S 1 ⊕ S S 2 = { 0 , 无溢出 1 , 有溢出 V=S_{S1} \oplus S_{S2}=\begin{cases} 0, & 无溢出 \\ 1, & 有溢出 \\ \end{cases} V=SS1SS2={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 2n1,超出此范围则溢出
  • 加法判断溢出:最高位产生的进位 = 1 =1 =1 时,发生溢出,否则未溢出。
  • 减法判断溢出:减法变加法,最高位产生的进位 = 0 =0 =0 时,发生溢出,否则未溢出。

八、乘除运算

1. 无符号整数乘法

  • 基本原理:逐位相乘,错位相加
    • 两个 n n n bit 的无符号数的乘法,可拆解为 n n n 轮加法运算
    • 根据乘数的各个 bit,决定每一轮加法运算 “+ 被乘数” 或 “+ 全 0”
    • 每一轮加法运算需要与上一轮加法运算的结果 “错位相加”
  • 32 位无符号数乘法运算电路结构和解释说明,接下来的运算过程基于此图
    在这里插入图片描述
  • 4 位简化版
    在这里插入图片描述

运算过程:

  • 开始:
    1. 被乘数、乘数分别放入寄存器 X 、 Y X、Y XY
    2. 乘积寄存器 P P P 置为 0
    3. 计数器 Cn \text{Cn} Cn 的初始值置为 n n n
  • 进行 n n n 轮处理:重复 n n n 轮加法、移位运算,直到计数器 Cn = 0 \text{Cn}=0 Cn=0
    1. 乘数寄存器 Y 的最低位,送入 “控制逻辑” 进行判断
      • Y Y Y 的最低位为 1,则执行加法,运算结果写回 P P P,加法产生的进位保存至进位触发器 C C C
      • Y Y Y 的最低位为 0,则什么也不做
    2. 将 【 C , P , Y C,P,Y CPY】视为整体,逻辑右移一位
    3. 计数器 Cn \text{Cn} Cn 减 1
  • 结束:当计数器 Cn = 0 \text{Cn}=0 Cn=0 时,乘法运算结束
    • 2 n 2n 2n 位【 P , Y P,Y PY】暂存乘法运算结果,但最终仅保留低 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. 带符号整数乘法

  • 与无符号整数乘法电路的不同
    1. 可能进行加法、减法
    2. 控制逻辑根据 2 bit( Y Y Y 的最低位、辅助位)决定本轮该如何处理
    3. 低位增加一个 “辅助位”
    4. 不保存最高位产生的进位信息
  • 32 位带符号数乘法运算电路结构和解释说明,接下来的运算过程基于此图
    在这里插入图片描述
  • 4 位简化版
    在这里插入图片描述

运算过程

前情提要:

  1. 带符号数(补码)乘法,符号位参与运算
  2. 当被乘数、乘数种有一个全为 0 时,结果直接得 0,不需要在进行后续的运算步骤
  • 开始:
    1. 将被乘数、乘数分别放入寄存器 X 、 Y X、Y XY
    2. 乘积寄存器 P P P 置为 0,“辅助位” 置为 0(辅助位就是图中的黄色块)
    3. 计数器 Cn \text{Cn} Cn 的初始值置为 n n n
  • 进行 n n n 轮处理:重复 n n n加 / 减法移位运算,直到计数器 Cn = 0 \text{Cn}=0 Cn=0
    1. 将乘数寄存器 Y Y Y 的最低位、辅助位,2 bit 送入 “控制逻辑” 进行判断
    2. 根据寄存器 Y Y Y 的最低位、辅助位,决定是 “+[x]”、“-[x]”、“+0”(记忆技巧:辅助位 - Y Y Y最低位)
      寄存器 Y Y Y 最低位辅助位本轮操作
      00+0
      01+[x]
      10-[x]
      11+0
    3. 将【 P 、 Y 、辅助位 P、Y、辅助位 PY、辅助位】视为整体,算数右移一位
    4. 计数器 Cn \text{Cn} Cn 减 1
  • 结束:当计数器 Cn = 0 \text{Cn}=0 Cn=0 时,乘法运算结束
    • 2 n 2n 2n 位【 P , Y P,Y PY】暂存乘法运算结果,但最终仅保留低 n n n 位【 Y Y Y】作为最终结果,因此可能发生溢出
    • 溢出判断:若 2 n 2n 2n 位的 n + 1 n+1 n+1 位不完全相同,说明发生溢出,并设置 OF 标志位 = 1 =1 =1
    • 溢出处理与无符号整数乘法一样

3. 实现乘法运算的方式

  • 计算机实现乘法运算的三种方式:
    1. 由 ALU、移位器、寄存器、控制逻辑组成的乘法电路(就是上面说的电路)
      • 该电路若实现 n n n bit 无符号数相乘,至少需要 n n n 个时钟
      • 改进方案:可以实现 “两位乘法”,每轮处理乘数寄存器 Y Y Y 的末尾 2 bit,此时仅需 2 n \frac{2}{n} n2 个时钟即可完成运算
    2. 阵列乘法器
      • 特点:可以在 1 个时钟内完成乘法运算
      • 4 × 4 4×4 4×4 位阵列乘法器示例图
        在这里插入图片描述
      • 阵列乘法器是快速乘法器种的一种。很多快速乘法器都可以在 1 个时钟内完成乘法运算
    3. 由逻辑运算(位运算、移位运算)、加 / 减运算等效实现乘法
      • 优点:在没有乘法运算电路、不支持乘法指令的计算机中,也可以等效实现乘法效果
      • 缺点:运算速度很慢(在非流水线计算机中,每条指令的执行都至少需要 1 个时钟)

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 位简化版在这里插入图片描述

运算过程:

  • 开始:
    • 正常情况:将数据放入寄存器:
      1. 除数放入寄存器 Y Y Y
      2. 被除数放入寄存器【 R 、 Q R、Q RQ】并完成零扩展
      3. 计数器 Cn \text{Cn} Cn 的初始值置为 n n n
    • 特殊情况检查:
      1. 如果除数为 0,发生 “除数为0” 异常,停止除法运算,调出操作系统的异常处理程序
      2. 如果 ∣ 被除数 ∣ < ∣ 除数 ∣ |被除数|<|除数| 被除数除数,则商 = 0,余数 = 被除数,除法器不必再执行
  • 进行 1 + n 1+n 1+n 轮处理(计算 1 + n 1+n 1+n 位商)
    • 上商规则:如果【 R R R】-【 Y Y Y】≥ 0,则上商 1,否则上商 0
    1. 第一轮:特殊处理,商溢出判断
      • 直接上商,若第一位商 = 1,发生 “商溢出” 异常,停止除法运算
      • 直接上手,若第一位商 = 0,说明不会发生 “商溢出”,不必保存这位商,也不让 Cn − − \text{Cn}-- Cn,除法运算继续

      第一位商不保存,仅用于商溢出判断

    2. 其余 n n n 轮处理
      1. 左移,空出的位用于上商
      2. 上商,背后的过程可能会进行加法 / 减法
        • 比如上商是 R − Y R-Y RY,如果差 < 0,需要恢复余数 R − Y + Y R-Y+Y RY+Y
      3. 计数器 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.111.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 的移码

      1. 将十进制真值 + 偏置值
      2. 按 “无符号整数” 规则转换为指定位数

      例: 2 + 127 = 129 ⟹ 10000001 2+127=129 \Longrightarrow 10000001 2+127=12910000001

    • 尾数的存储:规定小数点位置在 23 bit 之前。默认存储规格化尾数,小数点前的 1 省略(隐含,因此实际可表示 24 bit)
    • 基数不用专门存储,规定基数为 2 即可
  • double 双精度浮点型的存储
    • 占 64 bit = 1 bit 符号 + 11 bit 阶码 + 52 bit 尾数
      在这里插入图片描述
    • 符号、尾数、基数与单精度浮点型一样
    • 阶码:规定偏置值为 1023(211-1 - 1)

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×2126 + 1.0 × 2 − 126 +1.0×2^{-126} +1.0×2126
      正数最大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} +(2223)×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} (2223)×2127
      负数最大1, 00000001, 00…00 − 1.0 × 2 − 126 -1.0×2^{-126} 1.0×2126 − 1.0 × 2 − 126 -1.0×2^{-126} 1.0×2126
  • 非规格化(单精度)浮点数表示范围
    • 非规格化的阶码全 0、尾数不全为 0。因此阶码真值 = 1 - 偏置值
    • 尾数的小数点前隐含 0
      说明符, 阶, 尾二进制十进制
      正数最小0, 00000000, 00…01 + 0.00...01 × 2 − 126 +0.00...01×2^{-126} +0.00...01×2126 + 2 − 23 × 2 − 126 = + 2 − 149 +2^{-23}×2^{-126}=+2^{-149} +223×2126=+2149
      正数最大0, 00000000, 11…11 + 0.11..11 × 2 − 126 +0.11..11×2^{-126} +0.11..11×2126 + ( 1 − 2 − 23 ) × 2 − 126 = + ( 2 − 126 − 2 − 149 ) +(1-2^{-23})×2^{-126}=+(2^{-126}-2^{-149}) +(1223)×2126=+(21262149)
      负数最小1, 00000000, 11…11 − 0.11..11 × 2 − 126 -0.11..11×2^{-126} 0.11..11×2126 − ( 1 − 2 − 23 ) × 2 − 126 = − ( 2 − 126 − 2 − 149 ) -(1-2^{-23})×2^{-126}=-(2^{-126}-2^{-149}) (1223)×2126=(21262149)
      负数最大1, 00000000, 00…01 − 0.00...01 × 2 − 126 -0.00...01×2^{-126} 0.00...01×2126 − 2 − 23 × 2 − 126 = − 2 − 149 -2^{-23}×2^{-126}=-2^{-149} 223×2126=2149

4. 特殊状态

  • (单精度)特殊状态
    值的类型符号阶码尾数例子
    正零0全 0全 0+0正下溢
    负零1全 0全 0-0负下溢
    非规格化正数0全 0不全 0 0. 尾数 × 2 − 126 0.尾数×2^{-126} 0.尾数×2126 00200000 H = + 2 − 128 00200000\text{H}=+2^{-128} 00200000H=+2128
    非规格化负数1全 0不全 0 − 0. 尾数 × 2 − 126 -0.尾数×2^{-126} 0.尾数×2126 80200000 H = − 2 − 128 80200000\text{H}=-2^{-128} 80200000H=2128
    正无穷0全 1全 0 + ∞ +∞ +正数除以 0、正上溢
    负无穷1全 1全 0 − ∞ -∞ 负数除以 0、负上溢
    无定义数(非数)0、1全 1不全 0NaN零除以零、负数开根号等
  • 浮点数的上溢(Overflow)
    在这里插入图片描述
    • 运算结果大于最大规格化正数时称为正上溢;小于绝对值最大的规格化负数时称为负上溢
    • 正上溢、负上溢统称为上溢,也会翻译成溢出
    • 浮点数上溢的处理:
      • IEEE 754 规定,默认不响应浮点数溢出异常,不中断程序,除非程序员手动开启此类异常响应
      1. 浮点数运算部件将运算结果设为 + ∞ +∞ + − ∞ -∞
      2. 设置浮点数溢出异常标志位(如 x86 会将浮点运算单元 FPU 的 OE 标志位 Overflow Exception 置为 1)
  • 浮点数的下溢(Underflow)
    在这里插入图片描述
    • 若浮点数运算结果在 0 至绝对值最小的规格化正数之间时称为正下溢,在 0 至绝对值最小规格化负数之间时称为负下溢
    • 正下溢、负下溢统称为下溢
    • 浮点数下溢的处理:
      • IEEE 754 规定,默认不响应浮点数溢出异常,不中断程序,除非程序员手动开启此类异常响应
      1. 若结果落入非规格化区间,则用非规格化浮点数存储;若结果太小(真值逼近于 0)则按机器零存储
      2. 若下溢至机器零,设置浮点数下溢异常标志位(如 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 大于则跳转
  • 数的比较硬件步骤:
    1. 通过 “cmp 指令” 比较 a 和 b(cmp a, b),实质上是用 a − b a-b ab
    2. 相减的结果信息会记录在程序状态字寄存器(PSW,也称标志寄存器)中
      • 进位 / 借位标志 CF、零标志 ZF、符号标志 SF、溢出标志 OF
    3. 根据 PSW 的某几个标志位进行条件判断,来决定是否转移
      • je 2:表示 a = b a=b a=b 时跳转到 2
      • jg 2:表示 a > b a>b a>b 时跳转到 2
      • jump 2:不管 PSW 的各种标志位直接跳转到 2
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iFulling

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值