3.2加法和减法
- 1、加法:和手动加法一样,从右到左逐位相加。
- 2、减法:减数求补之后相加
- 3、 加法示例:
4、溢出
- 当两个加数符号相反时不会溢出。
- 当溢出发生时符号位可能被数值位占用而产生错误。
- 二进制补码溢出检测
- 两个无符号数加减时不会发生异常,是因为发生溢出时已经取模了,就像4位无符号数表示的8+8 =0;相加结果和2^4取余得到最终结果。
在addiu指令中就算操作是无符号的,立即数仍然是有符号的,因为它要从16位符号扩展到32位。
MIPS检测到 发生溢出时会产生异常,有些计算机系统中也叫中断,MIPS使用异常程序计数器(Exception Program Counter; EPC)来保存导致异常出现的指令的地址,指令mfc0(move from system control)将ECP地址存储到通用寄存器,从而MIPS软件可以通过寄存器跳转指令返回到 异常出现指令那里。
饱和(saturating)操作,当计算结果溢出时,结果被设置为最大的正数或者最小的负数。
3.3乘法
- 当乘数和被乘数分别为n和m位的时候,乘积是n+m位
3.3.1顺序乘法算法和硬件
如同手算一样,二进制乘法,只有0和1,所以只需要判断是否将被乘数移位后的结果加到中间结果上面。 第一版乘法硬件框图如下:
具体运行流程如流程图所示:
流程图中步骤1、2、3、需要重复32次才能得到最终的积,如果每步需要1个时钟周期,也就是说需要100个时钟周期才能完成这次乘法运算。为了提高计算效率,我们改进这个算法和硬件结构,让步骤1、2、3并行进行,也就是说只用一个时钟周期同时完成这3步。改进后的乘法运算硬件框图:
改进后的电路解析:乘积寄存器是64位的,其中左半部分用来在ALU中和被乘数相加,右半部分存放乘数。具体流程如下:
首先判断乘积寄存器最右端一位是否是1,若是,则将乘积寄存器左半部分与被乘数相加,同时乘积寄存器整体右移一位,然后判断移位是否达到32次,若是结束,负责继续循环。
3.3.2有符号乘法
和无符号乘法相同,只是需要提前记住符号位,当符号位不同时,积为负。
3.3.3更快速的乘法
采用超前进位,应用更多ALU和硬件,用硬件复杂度换取时间代价。
3.3.4Mips中的乘法
Mips提供了一对32位的寄存器(Hi和Lo)来容纳64位的积。并且提供了两条指令(无符号,有符号)mult和multu。
编译器可能会用移位来代替乘数为2的幂次的乘法运算
这里并没有溢出检测,只能由软件来实现这部分任务。