赞
踩
一、 实验目标:
二、实验内容
按照下面的实验步骤及说明,完成相关操作记录实验过程的截图:
首先,我们使用加法操作设计一个不检测溢出的乘法操作;完成后,我们对此进行优化,以期获得一个可以对溢出进行检测的乘法操作。(100分)
三、实验环境
硬件:桌面PC
软件:Windows,WinMIPS64仿真器
四、实验步骤及说明
本次试验分为两个部分:第一部分、用加法器设计一个不考虑溢出的乘法器;第二部分、用加法器设计一个考虑溢出的乘法器(编程熟练的同学,也可以用除法器、浮点加法器等替代)。
1、忽略溢出的乘法器
首先,我们得了解乘法器如何由加法器设计得到,此处,我们以32位乘法为例。
总共分为4步:
运行显示运行结果的例子如下,由于我们这里展示的是忽略了溢出的乘法,所以结果有两种:1、小于32位;2、大于32位。
第一种情况截图:
第二种情况截图:
根据上面的程序代码和截图,我们可以很清楚的看出,当结果小于32位时,结果正常;当结果大于32位时,结果只截取了低32位的结果,而高32位的结果直接忽略掉了。
2、溢出提示的乘法器
上述的程序,用加法实现了32位乘法,但是,其中,对溢出情况没有进行考虑是其中的弊端。这里,我们来完善上述的乘法器,使得该乘法器会在结果溢出时候提示。
其实,这个小优化是十分简单的,只需要对64位的寄存器中的高32位进行检测即可。当高32位为0时,说明结果没有溢出,否则,结果溢出。
上述代码运行结果也有两个,一个是没有溢出的情况下的结果,一个是溢出了的情况下的结果。
首先,我们看没有溢出的情况结果:
结果正确,其次,我们看溢出的情况结果如何:
可以看到,当结果溢出时,程序会给出提示“warning:result overflow”。
4 结束语
本实验介绍了通过加法器来设计乘法器的原理,并且在编写该实验程序的时候,我们更加了解了:1、计算机乘法器工作原理的内容;2、进一步熟练MIPS的编程方法;3、WinMIPS64的使用方法。当然,如果想要更加深入的学习,我们也可以课外继续编写对除法的模拟。
五、实验结果
代码一:
代码二:
请输入数1:
请输入数2:
输出结果:
溢出情况:
防溢出:
具体代码:
- .data
- CONTROL: .word 0x10000; # 控制寄存器的地址
- DATA: .word 0x10008; # 数据寄存器的地址
-
- mes1: .asciiz "输入 num1:\n"; # 提示用户输入num1的消息
- mes2: .asciiz "输入 num2:\n"; # 提示用户输入num2的消息
- mes3: .asciiz "答案是:\n"; # 输出答案的消息
-
- .text
- # 首先输出 mes1:
- lwu r8, DATA(r0) ; 无用指令,加载DATA地址
- lwu r9, CONTROL(r0) ; 无用指令,加载CONTROL地址
-
- daddi r8, r0, 8 ; DATA地址
- daddi r9, r0, 0 ; CONTROL地址
-
- lwu r8, (r8) ; 加载数据
- lwu r9, (r9) ; 加载控制寄存器
-
- daddi r11, r0, 4 ; 为输出 mes1 做准备
- daddi r1, r0, mes1 ; 获取mes1的地址
- sd r1, (r8) ; 保存mes1
- sd r11, (r9) ; 调用系统输出
-
- daddi r1, r0, 8 ; 为输入数据做准备
- sd r1, 0(r9) ; 获取被乘数
- ld r2, 0(r8)
- daddi r10, r2, 0 ; 将被乘数存储在r10中
-
- daddi r11, r0, 4 ; 为输出 mes2 做准备
- daddi r1, r0, mes2 ; 获取mes2的地址
- sd r1, (r8) ; 保存mes2
- sd r11, (r9) ; 调用系统输出
-
- daddi r1, r0, 8 ; 为输入数据做准备
- sd r1, 0(r9) ; 获取乘数
- ld r2, 0(r8)
- daddi r11, r2, 0 ; 将乘数存储在r11中
-
- # 循环:对于每一位乘数,如果乘数最低位为1,则进行加法操作
- daddi r12, r0, 0 ; r12用于存储乘法结果
- daddi r13, r0, 0 ; 初始化循环变量i
-
- loop:
- slti r15, r13, 32 ; 检查i是否小于32
- beq r15, r0, exit_loop ; 如果i >= 32,则退出循环
-
- andi r14, r11, 1 ; 获取乘数的最低位
- beq r14, r0, out_add ; 如果最低位为0,跳过加法
-
- # 进行乘法加法
- dadd r12, r12, r10
-
- out_add:
- dsll r10, r10, 1 ; 被乘数左移1位
- dsrl r11, r11, 1 ; 乘数右移1位
- daddi r13, r13, 1 ; i自增
- j loop
-
- exit_loop:
-
- daddi r11, r0, 4 ; 为输出 mes3 做准备
- daddi r1, r0, mes3 ; 获取mes3的地址
- sd r1, (r8) ; 保存mes3
- sd r11, (r9) ; 调用系统输出
-
- daddi r11, r0, 2 ; 为输出整数做准备
- daddi r1, r12, 0 ; 获取乘法结果
- sd r1, (r8) ; 保存
- sd r11, (r9) ; 调用系统输出
-
- halt
-
-
-
- 二:
- .data
-
- CONTROL: .word 0x10000; # 控制寄存器的地址
- DATA: .word 0x10008; # 数据寄存器的地址
-
- mes1: .asciiz "请输入 num1:\n"; # 提示用户输入num1的消息
- mes2: .asciiz "请输入 num2:\n"; # 提示用户输入num2的消息
- mes3: .asciiz "答案是:\n"; # 输出答案的消息
- mes4: .asciiz "结果溢出了。"; # 输出溢出消息
-
- .text
- # 首先输出 mes1:
- lwu r8, DATA(r0) ; 无用指令,加载DATA地址
- lwu r9, CONTROL(r0) ; 无用指令,加载CONTROL地址
-
- daddi r8, r0, 8 ; DATA地址
- daddi r9, r0, 0 ; CONTROL地址
-
- lwu r8, (r8) ; 加载数据
- lwu r9, (r9) ; 加载控制寄存器
-
- daddi r11, r0, 4 ; 为输出 mes1 做准备
- daddi r1, r0, mes1 ; 获取mes1的地址
- sd r1, (r8) ; 保存mes1
- sd r11, (r9) ; 调用系统输出
-
- daddi r1, r0, 8 ; 为输入数据做准备
- sd r1, 0(r9) ; 获取被乘数
- ld r2, 0(r8)
- daddi r10, r2, 0 ; 将被乘数存储在r10中
-
- daddi r11, r0, 4 ; 为输出 mes2 做准备
- daddi r1, r0, mes2 ; 获取mes2的地址
- sd r1, (r8) ; 保存mes2
- sd r11, (r9) ; 调用系统输出
-
- daddi r1, r0, 8 ; 为输入数据做准备
- sd r1, 0(r9) ; 获取乘数
- ld r2, 0(r8)
- daddi r11, r2, 0 ; 将乘数存储在r11中
-
- # 循环:对于每一位乘数,如果乘数最低位为1,则进行加法操作
- daddi r12, r0, 0 ; r12用于存储乘法结果
- daddi r13, r0, 0 ; 初始化循环变量i
-
- loop:
- slti r15, r13, 32 ; 检查i是否小于32
- beq r15, r0, exit_loop ; 如果i >= 32,则退出循环
-
- andi r14, r11, 1 ; 获取乘数的最低位
- beq r14, r0, out_add ; 如果最低位为0,跳过加法
-
- # 进行乘法加法
- dadd r12, r12, r10
-
- out_add:
- dsll r10, r10, 1 ; 被乘数左移1位
- dsrl r11, r11, 1 ; 乘数右移1位
- daddi r13, r13, 1 ; i自增
- j loop
-
- exit_loop:
-
- daddi r11, r0, 4 ; 为输出 mes3 做准备
- daddi r1, r0, mes3 ; 获取mes3的地址
- sd r1, (r8) ; 保存mes3
- sd r11, (r9) ; 调用系统输出
-
- daddi r11, r0, 2 ; 为输出整数做准备
- daddi r1, r12, 0 ; 获取乘法结果
- sd r1, (r8) ; 保存
-
- sd r11, (r9) ; 调用系统输出
-
- # 右移32次
- daddi r13, r0, 0 ; 重新初始化i
- loop2:
- slti r15, r13, 32 ; 检查i是否小于32
- beq r15, r0, exit_loop2 ; 如果i >= 32,则退出循环
- dsrl r12, r12, 1 ; 右移1位
- daddi r13, r13, 1 ; i自增
- j loop2
-
- exit_loop2:
-
- # 判断是否溢出
- beq r12, r0, out_print ; 当r12的高位不为零时打印溢出消息
-
- # 打印
- out_print:
- daddi r11, r0, 4 ; 为输出 mes4 做准备
- daddi r1, r0, mes4 ; 获取mes4的地址
- sd r1, (r8) ; 保存mes4
- sd r11, (r9) ; 调用系统输出
-
- halt
六、实验总结与体会
此次实验让我对mips有了更深的了解,但winmips64软件r8和r9老是出问题不知道是什么原因。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。