【计算机组成与设计:硬件/软件接口】第三章:计算机的算术运算
【计算机组成与设计:硬件/软件接口】第三章:计算机的算术运算
标签(空格分隔):【计算机组成与设计:硬件/软件接口】
第三章:计算机的算术运算
3.1 引言
3.2 加法和减法
- 对于二进制补码,什么时候发生溢出?
硬件规模总是有一定限制的,例如字宽只有32位。当运算超过这个限制,就会发生溢出。
首先看什么时候不会溢出。加法:当相加的两个源操作数符号相异时,不会发生溢出,因为二者的和必定不会大于其中的某一个操作数。若源操作数可以用32位表示,那么这个结果也必然可以用32位表示。减法规则相反,当源操作数符号相同时,不会溢出。例如 c - a可以视为 c + (-a),此时与加法不会溢出时情况相同。
何时发生溢出?当加法和减法之后的结果需要使用多余32位表示时会发生溢出。例如,如果两个正数相加但结果是负数,或者一个负数减去一个正数结果为正数,那么必然发生了溢出。
加减法发生溢出的条件: 对于无符号整数,由于无符号整数通常用于表示内存地址,这种情况下的溢出可以忽略。
-
MIPS 解决溢出的方法:
- add,addi,sub,这三条指令在溢出时产生异常。
- addu,addiu,subu,这三条指令在溢出时不会发生一场。
由于C语言忽略溢出,因此 MIPS C编译器总是采用无符号算术指令addu,addiu,subu,而不必考虑变量的类型。
算术逻辑单元(arithmetic logic unit,ALU):用来执行加法、减法,通常也包括逻辑与、逻辑或等逻辑操作。
- 异常:也叫中断,一种打断正常程序执行过程的事件,用于溢出检测。
- 中断:来自处理器外部的异常。
- 从本质上来说,异常或终端是一种打断正常过程的系统调用,产生溢出的指令地址保存在一个寄存器中,而后计算机会跳转到一个预先设定好的地址取执行相应的异常处理程序。保存异常地址的目的是为了在某些条件下能够在异常处理程序执行完毕之后返回源程序继续执行。
- 饱和(saturating)操作是通用微处理器中一个出场出现的特性,它意味着当计算结果溢出时,结果被设置为最大的整数或者最小的负数,而不像二进制补码运算那样采用取模操作来获得结果。注意,饱和操作更适合多媒体操作。
3.3乘法
- 乘法操作中,被乘数(multiplicand):第一个源操作数,乘数(multiplier):第二个源操作数,积(product):最终结果。一般而言,积的位数远远大于被乘数和乘数。事实上,在忽略符号位的情况下,积的位数等于乘数的位数与被乘数的位数。因此,乘数也需要考虑溢出的情况。
3.3.1 顺序的乘法算法和硬件
-
假设源操作数仅仅是正数。下图给出了硬件结构。
对于操作数的每一位的三个基本执行步骤:乘数的最低为(乘数的第0 位)决定了成功倍数是否被加到积寄存器上。第二步中的左移起着将被乘数左移的作用。第三部钟后的有一给出了下一个迭代中要使用的乘数位。这三个步骤重复执行32次才获得积。假设每个步骤花费一个时钟周期,那么100个时钟周期才可以完成两个32位数的相乘。以上算法很容易得到优化:当乘数位为1时,将乘数和被乘数进行移位,同时将被乘数和积相加。这样一来每一步只需要一个时钟周期。
3.3.2 有符号乘法
- 如何处理有符号乘法,最简单的方法是首先将被乘数和乘数转换为整数,并记录原先的符号位。
3.3.3 更快的乘法
- 思想:在乘法运算开始的时候通过检查乘数的32位,来判定被乘数是否被加上,快速的乘法运算的主要思想是为乘数的每一位提供一个32位加法器,一个用来输入被乘数和一乘数位相与的结果,另一个是上一个加法器的输出。
- 方法:
3.3.4 MIPS中的乘法
- 一对单独的32位寄存器来容纳64位的积,分贝是Hi和Lo。
- 为了产生正确的有符号积和无符号积,MIPS提供了两条指令:mult 和 multu.
- 为了取得32位的整数积,通常使用mflo指令。
3.3.5 小结
- 乘法运算指示简单的移位和加法。
3.4 除法
- 在除法的操作中,两个源操作数被称为被除数(dividend)和除数(divisor),结果为 商(quotient),第二个结果为 余数(remainder).它们之间的关系可以表示为其中余数小于除数。
3.4.1 除法算法及其硬件结构
- 开始时,32位的商寄存器设为 0,算法每次的迭代将除数向右移一位,所以开始时将除数放置在64为除数寄存器的左半边,然后每次右移一位来和被除数对齐。玉树寄存器初始化为被除数。
3.5 浮点运算
- 科学记数法(scientific notation):十进制小数点左边只有一位整数的计数法。
- 规格化数(normalized):没有前导零的浮点计数法。
- 浮点数(floating point):二进制小数点不固定的表达数的计数法。
- 对实数采用规格化形式的标准科学技术法的三个优点:1. 简化了浮点数的数据交换,2. 简化了浮点算术算法,3. 提高了可一个字存储的数的精度。
3.5.1 浮点表示
- 尾数(fraction):位于浮点数和尾数字段,其值在 0 和 1 之间。
- 指数(exponent):位于浮点数的指数字段,表示小数点的位置。
- 考虑到字的大小是固定的,浮点表示的设计者必须在尾数位宽和指数位宽之间找出折中的办法。浮点数通常是多个字的宽度,MIPS中,s为浮点数的符号(1表示负数),指数域为8位宽(包括指数的符号位),尾数域为23位宽,这种表示成为符号和数值(sign and magnitude), 因为符号和数值的位置是相互分离的。
一般浮点数的表示形式:其中F为小数域的值,E为指数域的值。
浮点表示法使得MIPS计算机有很大的数值表示范围,小到 ,大到 ,但请注意,它和无穷是不同的。也会存在一些数字因为太大而不能表示。溢出依旧会发生。 - 上溢(overflow):正的指数太大而导致指数域放不下的情况。
- 下溢(underflow)):负的指数太大而导致指数域放不下的情况。
一种减少上溢和下溢的方法:采用更达的指数格式。C语言中成为double,基于double的操作成为双精度(double precision)浮点算术,指的是浮点数由两个32位的字表示。单精度(single precision)浮点就是前面的格式,指的是浮点数由一个32位的字表示。
IEEE 754 浮点标准:
双精度浮点数占用了两个MIPS字,如下所示。其中,s表示符号,指数域为11位,尾数与为52位。
MIPS双精度的表示范围小到 ,大到 .它的主要的优势还是通过提供更多的有效位数来实现更达的表示精度。
包括前面单精度浮点数,也是IEEE 754 浮点标准的一部分。- 为了将更多的数据为打包到有效位数(significand)部分,IEEE 754 标注甚至隐藏了规格化二进制数的前导位 1 .
因此,在单精度浮点数下,数有24位宽(隐含的规格化二进制数的前导位1和23位尾数);在双精度的情况下,数有523位宽(1+52)。为了精确,我们用术语有效位数来表示24位或者53位的数,就是隐含1加上位数。
因为 0 没有前导位 1 ,它的指数保留为0,所以硬件就不会将前导位1 加到尾数上。其余的数使用前面的形式其中F为 0 和 1 之间的数。
准确而言是
其中,无穷用来处理 除0中断;非数字用来推迟程序中的一些测试和决定。 - 为什么符号位放在最前面?因为 IEEE 754的设计者希望浮点能够比较快速地处理整数比较。
为什么将指数放在有效位数前?因为这样可以简化用整数比较指令来处理地浮点数分类,有着相同符号的情况下,指数越大数值越大。
-
带偏阶的计数法(biased notation):在IEEE 754中单精度的偏阶为 127,双精度的指数偏阶为 1023。带上偏阶之后,浮点数的表示为:
3.5.2 浮点加法
-
为了说明浮点加法的问题,我们将两个采用科学记数法的数字相加:,假设我们只能存储 4 个十进制有效数字和两个十进制指数。
步骤:- 为了能让两个数字相加,我们必须将有较小指数的数指向有较大指数的数字。
即 ,由于只能表示4 位十进制数,所以需要移位,最终结果为 . - 将有效数相加:.
- 因为和不是规格化科学记数形式,因此需要规格化,即 .
- 由于有效数只有 4位十进制数那么长(不包括符号位),所以我们需要进行舍入,依照四舍五入法则,有
- 为了能让两个数字相加,我们必须将有较小指数的数指向有较大指数的数字。
浮点加的基本结构: