ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2021-11-09 13:01:18  阅读:197  来源: 互联网

标签:除法器 结果 被除数 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有