一、实验目标:
了解WinMIPS64的基本功能和作用;
熟悉MIPS指令、初步建立指令流水执行的感性认识;
掌握该工具的基本命令和操作,为流水线实验做准备。
二、实验内容
按照下面的实验步骤及说明,完成相关操作记录实验过程的截图:
1)下载WinMIPS64;运行样例代码并观察软件各个观察窗口的内容和作用,掌握软件的使用方法。
2)学会正确使用WinMIPS64的IO方法。
3)编写完整的排序程序。
三、实验环境
硬件:桌面PC
软件:Windows,WinMIPS64仿真器
四、WinMIPS64软件使用
1)安装
解压给出的winmips64.zip压缩文件到给定的工作目录中(如在我的电脑中的路径是E:\winmips64)。
2)开始和配置WinMIPS64
双击winmips64.exe文件后,打开了WinMIPS64模拟器。
在主窗口中,我们可以看见七个子窗口,和一条在底部的状态栏。这七个子窗口分别是Pipeline, Code, Data,Registers, Statistics, Cycles和Terminal。这七个窗口的作用如下:
- Pipeline窗口: 展示MIPS64处理器的五级流水线结构及浮点操作单元,指示当前指令在不同流水段的状态。
- Code窗口: 显示存储器内容,包括地址、机器代码和汇编指令。通过颜色标识指令处于“取指”、“译码”等不同阶段。
- Cycles窗口: 显示流水线的时空图,指令执行过程的可视化,帮助识别指令间的依赖关系和数据停滞情况。
- Data窗口: 观察内存中的数据,包括地址和内容。可通过双击或右键修改整型或浮点型数据。
- Registers窗口: 显示寄存器中的值,指示当前写入和前递状态。允许用户交互式修改寄存器值。
- Statistics窗口: 记录模拟周期的统计数据,包括指令数、执行周期数、暂停周期数等,提供性能分析信息。
- Terminal窗口: 显示运行过程中输出的信息和状态,如数据相关的错误提示等,帮助用户调试和理解模拟过程。
3)装载测试程序
用标准的text编辑器来新建一个名为sum.s的文件,这个文件的功能是,计算两个整数A、B之和,然后将结果传给C。
首先使用asm.exe程序检测一下sum.s是否合法,检测方法为用命令行输入asm.exe 目标检测文件(.\asm.exe .\sum.s),可以发现下图使用asm.exe检测之后,没有错误(0 errors),即sum.s编译非常顺利。
下面我们将sum.s装载到winmips.exe程序中。打开winmips程序之后,使用快捷键“ctrl + o”打开文件进行装载,点击对应的文件即可。将sum.s加载到 winmips64程序中,得到初始化页面。
不断地按下F7(逐步进行),让程序运行,得到下图,可以发现一些窗口发生了变化。在运行的过程中,左上角Cycle,PipeLine和Code窗口出现了一些彩色标注的方块区域,Registers和Data窗口没有发生什么变化,statistics窗口有一些行列数据发生了变化。
通过查阅手册和相关资料,我们了解到,Cycles、Pipeline和Code窗口主要展示程序运行过程中指令的执行过程。这些窗口标识了每条指令所处的阶段,包括“取指”、“解码”、“执行”、“访存”和“写回”,与课程内容紧密对应。
Registers和Data窗口则提供了程序运行过程中寄存器和内存的数据状态。最后,Statistics窗口记录了程序运行过程中的各项统计信息。此外,还有一个终端窗口,用于与程序进行交互,尽管在这个程序中没有使用到。
在对这些窗口有了初步了解后,我们可以逐步跟踪程序运行,观察不同时间点的状态。计算机能够像流水线一样同时处理多条指令,以“取指”、“解码”、“执行”、“访存”和“写回”并行执行,从而提高运行效率。下图展示了程序运行结束后的状态。可以看到,在某些时刻,Cycles窗口中,计算机仍在进行取指和解码操作,这导致红色方块的执行模块处于空载阶段。从Cycles窗口在程序结束后的状态图中,可以发现当ID和IF模块执行完成之后,EX模块也开始继续往下执行了。
五、作业一:终端IO简单实例
1)程序设计
使用winmips64的终端来实现程序的输入输出,以”hello world”程序为例。首先,需要知道I/O区域的内存映射,一个是控制字,一个是数据字,具体结构如下:
控制字(CONTROL):
地址:通常在一个特定的内存地址,例如 0x10000。
功能:用于指示当前I/O操作的状态或类型。不同的值代表不同的操作,比如读取、写入或设置状态。
数据字(DATA):
地址:通常在另一个特定的内存地址,例如 0x10008。
功能:存储要发送到终端的数据或接收从终端输入的数据。
通过这两个区域,程序可以通过设置控制字和相应的数据字实现与终端的交互。具体的映射和使用方式可能因系统和具体实现而有所不同。
程序的运行逻辑如下:
(1)定义数据区:只需定义字符串、存储数据和控制变量的地址。
(2)代码区处理:
将字符串地址(如0x10008)加载到寄存器中。
将字符串内容存储到指定的内存地址。
将变量值4存储到地址0x10000,以指示程序打印字符串。
当完成以上这些步骤后,程序会将0x10008中的数据打印到终端,输出“hello world”。
(3)代码实现
.data string: .asciiz "hello, world!" # define string CONTROL: .word32 0x10000 # define control address DATA: .word32 0x10008 # define data address .text main: lwu r30, DATA(r0) # load 0x10008 to r30 |