《计算机组成原理:硬件/软件接口》(MIPS版)第三章:算术运算

本文详细介绍了计算机组成原理中的算术运算,包括整数的符号扩展、大小端编址,定点加减法的溢出处理,乘法运算的改进方法,以及除法和浮点数运算的原理、IEEE754标准和MISP指令。重点讲解了浮点数的表示范围、加法和乘法,以及溢出判断。
摘要由CSDN通过智能技术生成

前言

本系列文章将梳理《计算机组成原理》这门课的相关知识点,教材使用的是《计算机组成原理:硬件/软件接口》MIPS版,原书第五版。

本文所属章节为算术运算章节,重点内容为整数乘法和除法的改进版原理、IEEE754标准以及浮点加法和乘法


一. 整数表示

这部分不是重点,补码反码这些都在《数字逻辑》里面学过了,读者应该已经掌握。我们重点讲一下符号扩展和大小端编址两个概念。

1. 符号扩展

什么是符号扩展?我们以addi $t0,$t1,100为例。

因为addi的第一个操作数是32位的补码寄存器,第二个操作数却是16位的补码立即数,所以需要进行符号扩展后才能运算。具体怎么操作呢?只需要将最高位,即符号位复制到高16位即可

注意:无符号数加法指令addiu指令,也是按照符号位进行扩展!所以如果要加载32位立即数,不能用addiu指令替代ori指令!

2. 大小端编址

大端编址:高位放低地址。以FFF0为例子,内存从上往下看是内存地址降低的方向,那么从上到下依次是F0、FF。
小端编址:高位放到高地址。

二. 定点加减法

1. 溢出的概念

  • 上溢:正+正,正-负,即超出对符号位产生进位
  • 下溢:负+负、负-正,即对符号位产生借位
  • 双符号位判断溢出
    • 00:结果为正,无溢出
    • 01:结果为正,正溢。
    • 10:负溢。
    • 11:结果为负,无溢出。

在这里插入图片描述

  • 溢出的处理
    • 由 ALU中的硬件进行溢出检测
    • 产生一个异常(中断
    • 将产生溢出的指令地址保存到异常程序计数器(EPC)中
    • 跳到一个预先设定好的地址去执行相应的异常处理程序
  • 溢出的产生
    • 有符号数会加法和减法会产生,无符号数不会!

这里补充两条关于字节的处理指令:
lbu:取无符号字节,将一个字节装入寄存器的最低8位。寄存器空余位由‘0’填满
lb: 取字节(有符号),将一个字节装入寄存器的最低8位,寄存器空余24位由符号位扩展填满

2. ALU(非重点)

这里只是简单过一遍ALU的原理。这块基本不太考察硬件设计。

2.1 加法器复习

在这里插入图片描述

2.2 ALU控制线

这块内容在第四章也有涉及到。

在这里插入图片描述

2.3 ALU的特点

  • 32位ALU:行波进位
    • 低位进位输出指向高位进位输入。最低位的进位输入控制减法。
    • 为支持slt指令,如果rs<rt成立,将1从最高位指向最低位的Less信号。
    • 为实现溢出检测,最高位ALU会输出溢出信号
  • 改进ALU:超前进位
    • 32位的ALU行波进位意味着每次都要通过AND和OR各一次,产生64个门延迟。
    • 超前进位加法器的门延迟:要执行n位的加法,求出n是4的几次方向上取整,再乘以2加1 (具体推导有点复杂,记住结论)
    • 例如, l o g 4 32 ? = 3 , 3 ∗ 2 + 1 = 7 log_{4}32?=3,3*2+1=7 log432?=332+1=7,只需要7个门延迟。加速比高达9倍。
    • 信号:overflow为1表示溢出,zero为1表示结果为0.

三. 乘法运算及其改进

1. 未改进版乘法分析

  • 乘法运算的基础知识
    • 第一个乘数:被乘数。
    • 第二个乘数:乘数。
    • 结果:中间积。
  • 未改进版算法:流程图如下图所示
    • 测试乘数第0位。
    • 如果是1,将被乘数加到积上,结果放到积寄存器。
    • 将被乘数寄存器左移1位。
    • 乘数寄存器右移1位。
    • 判断是否重复了32次,如果是就结束。否则回到第一步。

在这里插入图片描述

  • 电路特点:三个寄存器。
    • 64位的积寄存器。
    • 32位乘数寄存器。
    • 64位的被乘数寄存器(因为需要一直左移)
    • ALU:64位的ALU

在这里插入图片描述

2. 改进版乘法运算

  • 前面的算法缺陷
    • 空间:被乘数寄存器左移后,低32位就空闲了,有点浪费空间。
    • 时间:三个执行步骤会执行32轮,大约需要100个时钟周期。

思考:积寄存器是增长的,乘数寄存器是减小的,能不能综合利用?

  • 改进版
    • 将乘积寄存器和乘数寄存器拼接为乘积乘数寄存器
    • 被乘数只有32位,并且不动
    • 因为移位是相对的,只需要让积相对于被乘数右移即可
    • 将ALU改进为32位
  • 门电路

门电路

  • 改进后的算法步骤
    在这里插入图片描述

  • 以2x3为例,展示算法流程:

    • 初始化:被乘数0010一直不变,积/乘数0000/0011,一共4位,该进行4轮运算。
    • 第一轮:判断,得知积/乘数寄存器最右边是1
      • 积+=被乘数:注意是加在高位哦。0010/0011
      • 寄存器右移(针对的都是积/乘数寄存器):0001/0001
    • 第二轮:依旧是积/乘数寄存器最右边是1
      • 积+=被乘数:0011/0001
      • 寄存器右移:0001/1000
    • 第三步:最右是0,右移即可,0000 1100
    • 第四步,最右是0,右移即可,0000 0110
    • 所以,答案就是0110啦!

3. MISP乘法指令

  • 使用两个32位寄存器存放64位的乘积HiLo
  • 两条乘法指令(R型,rd=0):
    • 乘法:mult $S2, $S3
    • 无符号乘法:multu $S2, $S3
    • 注意:64位乘积存放在Hi,Lo中!
  • 两条取乘积指令(R型,rs=0,rt=0) :
    • 从Lo寄存器取数:mflo $S1
    • 从Hi寄存器取数:mfhi $S1

四. 除法运算及其改进

1. 未改进版除法

  • 原理:我们以手算除法为案例,本质上就是比较余数和除数的大小关系,从而决定商的大小,即:
    在这里插入图片描述
  • 硬件结构
    在这里插入图片描述
  • 硬件解释
    • 32位除数:放在除数寄存器的左半边,每次迭代都要右移。
    • 被除数:放到64位余数寄存器中,每次迭代向商寄存器的最低位添加0或1.
    • 一共要进行33次迭代。
  • 算法分析:每次迭代中
    • 余数 - 除数
    • 根据结果,决定继续往下或者恢复余数
    • 根据结果,确定商为0或者1
      在这里插入图片描述

2. 改进版除法(重点)

  • 硬件结构
    • 商寄存器和余数寄存器的右半部分拼接在一起。
    • 被除数放到余数/商寄存器的右半部分。
    • 余数和商一起左移。

在这里插入图片描述

  • 案例分析:以7/2为例。
    在这里插入图片描述

最后,左边是余数,右边是商。

说实话我也不太理解这个原理,但是就考试而言,只需要记住推演流程:
除数不变,被除数初始放在余数商寄存器的右边,然后每次左移,如果说余数>0,就设置商最后一位是1,如果说余数小于0,就回复余数,确定最后一位是0
一共只需要迭代n次,即对于32位的除法,一共只需要迭代32次。

3. MISP中的除法指令

  • 两个32位寄存器:
    • Hi 存放余数
    • Lo 存放商
  • 除法:div $S2, $S3
  • 无符号除法:divu $S2, $S3

五. 浮点数表示及运算

1. 浮点数规格化

我们用-0.75为例子,首先需要知道如何将十进制数转换为二进制数

其实非常简单,就是不断乘以2,然后取最高位即可。转换后是-0.11

然后,我们将二进制数字转换为以2为基数的科学计数法,这个过程就叫做规格化

在上面的例子中,也就是 − 1.1 ∗ 2 − 1 -1.1 * 2^{-1} 1.121。可以发现,规格后的数字,小数点左边一定是1。

对于浮点数,有三个重要信息需要知晓:

  • 正负—符号位
  • 尾数—精度
  • 指数—大小

2. IEEE754 单/双精度浮点数表示

IEEE754标准如下:
在这里插入图片描述

对于单精度,其位数如下:
在这里插入图片描述
对于双精度,其位数如下:

在这里插入图片描述

拿上面的例子来说明,-0.11的符号位是1,指数位置是 − 1 + 127 = 126 -1+127=126 1+127=126,用IEEE754表示为尾数部分是1后面全0,即1 01111110 1000....000

Q:偏阶是怎么来的?

A:8位,我们的偏阶是 2 7 − 1 2^7-1 271。如果我们是双精度,也就是11位的指数域,那么偏阶就是 2 10 − 1 = 1023 2^{10}-1=1023 2101=1023

  • IEEE表示注意事项
    • 指数域为0,尾数为0,整个数就是0。
    • 指数域为0,尾数非0,非规格化数
    • 指数1-254,表示真正浮点数。
    • 指数255,如果尾数是0,表示INF
    • 指数255,尾数非0,表示NaN

2.1 浮点数表示范围

  • 对于单精度
    • 最小:1.(23个0) * 2 − 126 2^{-126} 2126
    • 最大:1.(23个1) * 2 127 2^{127} 2127
  • 对于双精度
    • 最小值:1.(52个0) * 2 − 1022 2^{-1022} 21022
    • 最大值:1.(52个1) * 2 1023 2^{1023} 21023

3. 浮点加法、浮点乘法

3.1 浮点的溢出

  • 上溢:正的指数太大而导致指数域放不下的情况。
  • 下溢:负的指数太大而导致指数域放不下的情况。

3.2 浮点加法

  • 算法分析
    • 第一步,小对大。指数小的转换为大的。
    • 第二步,尾数相加
    • 第三步,规格化
    • 第四步,查询四舍五入以及指数是否溢出。高于127叫做上溢,低于-126叫做下溢。(注意,加法是运算结果溢出,这里是指数的溢出。

以0.5+0.4375为例,首先规格化一下,0.5 = 1.0 ∗ 2 − 1 1.0 * 2^{-1} 1.021,0.4375 = 1.11 ∗ 2 − 2 1.11 * 2^{-2} 1.1122

在这里插入图片描述
下面给出流程图供参考:
在这里插入图片描述

3.3 浮点乘法

  • 算法分析
    • 第一步,将真正的指数相加。
    • 第二步,有效位相乘。
    • 第三步,规格化。
    • 第四步,四舍五入以及溢出检查。
    • 第五步,定符号,我们是一开始记住符号的。

在这里插入图片描述

3.4 MISP浮点指令(了解)

  • 寄存器
    • 存放32位单精度浮点数: $f0, $f1, … $f31
    • 存放双精度浮点数: f 0 / f0/ f0/f1, f 2 / f2/ f2/f3, …
  • 存取指令
    • lwcl, ldcl, swcl, sdcl(e.g ldcl $f8, 32($sp
  • 运算指令
    • 单精度:add.s, sub.s, mul.s, div.s
    • 双精度:add.d, sub.d, mul.d, div.d
  • 比较:c.x.s,c.x.d
  • 分支:bclt( cond=1时跳转)、bclf( cond=0时跳转)

至此,第三章算术运算的内容全部梳理完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值