WinMIPS64之32位乘法器和除法器的模拟实验
作者:互联网
WinMIPS64之32位乘法器和除法器的模拟实验
文章目录
一、实验内容
- 第一部分:用加法器设计一个不考虑溢出的乘法器
- 第二部分:用加法器设计一个考虑溢出的乘法器
- 第三部分:用减法器设计一个除法器 (额外尝试)
二、实验环境
硬件:桌面PC
软件:Windows,WinMIPS64仿真器
三、实验步骤
1. 忽略溢出的乘法器
总共分为4步:
- 测试乘数最低位是否为1,是则给乘积加上被乘数,将结果写入乘积寄存器;
- 被乘数寄存器左移1位;
- 乘数寄存器右移一位;
- 判断是否循环了32次,如果是,则结束,否则返回步骤1。
图0 乘法流程说明图
思路:首先将输入的数据在内存中指定的方式固定输入,主要通过上述4步实现忽略溢出的乘法逻辑,在程序运行结束后观察目标寄存器的值。最后完善输入和输出即可。
- 固定输入时
图 1 乘法逻辑的实现
通过asm.exe检测语法无误后在winmips64上执行结果如下,可以观察到此时r5寄存器的值已经变为f,即实现乘法逻辑。
图 2 初步结果
- 将输入改为用户输入,增加输出部分:
输入和输出部分都需要操作Control和Data中的值,开始部分的修改如下:
图 3 忽略溢出的乘法器代码(一)
中间的循环体依旧保持不变:
图 4 忽略溢出的乘法器代码(二)
最后输出提示语以及结果即可:
图 5 忽略溢出的乘法器代码(三)
- 验证结果如下:
图 6 验证结果(一)
图 7 验证结果(二)
2. 溢出提示的乘法器
思路:基于第一个忽略溢出的乘法器做优化,这个小优化是十分简单的,只需要对64位的寄存器中的高32位进行检测即可。当高32位为0时,说明结果没有溢出,否则,结果溢出。
溢出提示只需要额外设置提示字符串Str3以及右移最终的结果32位观察高位是否为0即可,若为0,则无溢出,若不为0,则发生溢出。
图 8 溢出提示的乘法器
注意不能直接右移立即数32位,编译不允许。其中在.data区域额外声明警告字符串:
.data
STR3: .asciiz "warning: result overflow\n";
分别测试非溢出状态以及溢出状态的乘法器结果如下:
图 9 溢出提示乘法器结果(一)
图 10 溢出提示乘法器结果(二)
可以见到,当存储结果的R5寄存器高32位的值非0,故R20也非0,程序输出溢出提示。
3. 基础除法器的实现
思路1:通过比较大小累减获得商和余数
a、比较被除数和除数的大小;
b、如果被除数比较大,将被除数减去除数,商加1;
c、循环步骤a和b,直到被除数比除数小,这时候被除数剩下的就是余数,商就是结果(初值为0)。
思路2:通过移位和累减获得商和余数
a、比较被除数和n*除数的大小;(其中n为移位的位数,可以理解为步骤一中一次性减掉的除数)
b、如果被除数比较大,将被除数减去n*除数,商加n;
c、循环步骤a和b,直到被除数比1*除数小,这时候被除数剩下的就是余数,商就是结果(初值为0)。
显然,思路2 使用移位的操作是基于思路一的步骤的,效率比思路 1 快许多。当除数很小时(比如1),思路 1 执行的循环体循环次数就会非常多。
- 无移位的简单除法器
图 11 基础除法器的实现
在WinMIPS64中执行,开始时R3,R4,R5分别对应被除数,除数和商:
图 12 寄存器初始数值
程序结束后,R3存储余数,R5存储商:
图 13 运行结果
显然13÷3 = 4 ……1,验证成功。
- 移位实现的除法器
每次被除数减去的除数是从大到小的,所以我们需要在开始的时候将除数放置在 64 位除数寄存器的左半边,然后每次右移一位来和被除数对齐:
主要代码如下:
图 14 移位除法
最终结果如下:
图 15 除法结果
至此实现了一个简单的除法器。
4. 乘除中正负号的处理
上述实现的乘除法都没有考虑到正负数的情况,如果异号,没有溢出的情况下也会计算错误。
解决思路:记录两数的符号,同号的结果为正,异号的结果为负。
分别处理两个输入的数据,如果是负数,则通过取反加一变成正数,得出正确的正数乘除结果;
最后通过一开始的符号位判断,如果是负数则对计算结果进行取反加一操作。
注意点:由于 MIPS 指令不支持 NOT ,所以可以通过异或操作来得到相同的结果。
即 reg xor 0xffff…
相关代码如下:
在data区域声明一个ALLONE,表示全都是1。
.data
ALLONE: .word 0xffffffffffffffff
图 16 取反加一操作
最后通过判断被乘数的符号位(R25)与乘数的符号位(R26)比较是否相同,若不同则进行取反加一的操作(等同于加负号)。
图 17 最终结果判断
最终结果如下:
图 18 运行结果
四、实验总结
- 乘法器的实现
本次实验了解了通过加法器实现32位乘法器的逻辑,通过累加与位移的循环实现了加法代替乘法。每次某一位上的累加都是基于乘数该位的有与无,而每次位移也体现了该位的权重,越高位的累加,之前的位移数也越多。
- 除法器的实现
本次实验额外尝试的除法器实现与乘法器相比有些不同,虽然不需要判断是否溢出,但是需要提前将除数左移32位,再不断右移。同时左移商与累减被除数。需要注意的是,由于被除数最后会减成余数,故如果需要保存被除数的话需要额外的寄存器。
- 更高位的思考
本次实验由于是使用64位的寄存器实现32位的乘法,所以比较简单。如果需要实现64位的乘法,则 不能使用判断高位的方式 实现,因为需要将乘积放入两个寄存器中,同时需要特判最终结果的符号位。
与乘法器相比有些不同,虽然不需要判断是否溢出,但是需要提前将除数左移32位,再不断右移。同时左移商与累减被除数。需要注意的是,由于被除数最后会减成余数,故如果需要保存被除数的话需要额外的寄存器。
标签:除法器,结果,被除数,WinMIPS64,除数,32,乘法器,溢出 来源: https://blog.csdn.net/HYY_2000/article/details/121199592