其他分享
首页 > 其他分享> > WinMIPS64之32位乘法器和除法器的模拟实验

WinMIPS64之32位乘法器和除法器的模拟实验

作者:互联网

WinMIPS64之32位乘法器和除法器的模拟实验

文章目录

一、实验内容

二、实验环境

硬件:桌面PC

软件:Windows,WinMIPS64仿真器

三、实验步骤

1. 忽略溢出的乘法器

总共分为4步:

  1. 测试乘数最低位是否为1,是则给乘积加上被乘数,将结果写入乘积寄存器;
  2. 被乘数寄存器左移1位;
  3. 乘数寄存器右移一位;
  4. 判断是否循环了32次,如果是,则结束,否则返回步骤1。

图0 乘法流程说明图

根据上面的步骤,当结果小于32位时,结果正常;当结果大于32位时,结果只截取了低32位的结果,而高32位的结果直接忽略掉了。

思路:首先将输入的数据在内存中指定的方式固定输入,主要通过上述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 运行结果

四、实验总结

  1. 乘法器的实现

本次实验了解了通过加法器实现32位乘法器的逻辑,通过累加与位移的循环实现了加法代替乘法。每次某一位上的累加都是基于乘数该位的有与无,而每次位移也体现了该位的权重,越高位的累加,之前的位移数也越多。

  1. 除法器的实现

本次实验额外尝试的除法器实现与乘法器相比有些不同,虽然不需要判断是否溢出,但是需要提前将除数左移32位,再不断右移。同时左移商与累减被除数。需要注意的是,由于被除数最后会减成余数,故如果需要保存被除数的话需要额外的寄存器。

  1. 更高位的思考

本次实验由于是使用64位的寄存器实现32位的乘法,所以比较简单。如果需要实现64位的乘法,则 不能使用判断高位的方式 实现,因为需要将乘积放入两个寄存器中,同时需要特判最终结果的符号位。
与乘法器相比有些不同,虽然不需要判断是否溢出,但是需要提前将除数左移32位,再不断右移。同时左移商与累减被除数。需要注意的是,由于被除数最后会减成余数,故如果需要保存被除数的话需要额外的寄存器。

标签:除法器,结果,被除数,WinMIPS64,除数,32,乘法器,溢出
来源: https://blog.csdn.net/HYY_2000/article/details/121199592