当前位置: 首页 > news >正文

科讯cms 网站地图阿里云域名注册入口

科讯cms 网站地图,阿里云域名注册入口,成都网站制作公司电话,网站开发代理一、实验目标: 了解WinMIPS64的基本功能和作用; 熟悉MIPS指令、初步建立指令流水执行的感性认识; 掌握该工具的基本命令和操作,为流水线实验做准备。 二、实验内容 按照下面的实验步骤及说明,完成相关操作记录实验…

一、实验目标:

了解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

daddi r31, r0, string                     # load string address to r31

sd r31, (r30)                             # store string address at 0x10008

lwu r30, CONTROL(r0)                      # load 0x10000 to r30

daddi r31, r0, 4                          # load 4 to r31

sd r31, (r30)                             # store 4 at 0x10000,print string

halt                                      # stop program

上面代码主要用了lwu,daddi,sd这三个指令:

(1)lwu:从内存中加载一个32位的无符号字(word)到寄存器中。

用法:lwu 寄存器, 偏移(基址寄存器)。如lwu r30, DATA(r0)表示从地址DATA(0x10008)加载一个无符号字到寄存器r30。

(2)daddi:将一个立即数与指定寄存器中的值相加,结果存储在目标寄存器中。这个指令用于处理64位数据。

用法:daddi 目标寄存器, 源寄存器, 立即数。如daddi r31, r0, string表示将string的地址加到寄存器r0(即0),结果存储在r31中。

(3)sd:将一个64位的双字(doubleword)从寄存器存储到内存的指定地址。

用法:sd 源寄存器, (目标地址寄存器)。如sd r31, (r30)表示将寄存器r31中的值存储到寄存器r30所指向的内存地址中。

2)检查合法性

用asm.exe检验一下程序的正确性,在终端中输入\asm.exe .\helloworld.s,得到如下的结果,没有错误(0 errors),即helloworld.s编译非常顺利。

3)结果运行

将helloworld.s加载到winmips64中,不断地按下F7之后进行单步运行,得到下图的结果。得到cycles顺利地进行了流水执行指令,没有raw stalls的情况发生,然后看终端,可以得到打印出了“hello,world!”。

六、作业二:编写排序算法

1)程序设计

实现对一个整数数组的冒泡排序(从小到大),并在终端中输出排序前后的数组数据。程序逻辑如下

数据区定义:定义了输出字符串(排序前和排序后)、控制地址、数据地址、栈指针、标志变量和待排序的数组。

初始数组数据自定义为:9,0,7,2,4,3,1,6,8,5

(1)主程序:

首先加载栈指针(SP)和控制、数据地址(CONTROL和DATA)。

打印排序前的数组:设置输出格式为字符串,加载"Before sort"字符串并存储地址,然后触发打印。设置输出格式为整数,循环遍历数组,逐个将元素存储到数据地址,触发打印。

(2)冒泡排序:调用bubblesort函数对数组进行排序。

bubblesort内部:

分配栈空间并保存返回地址和一些寄存器的值。

使用两层循环进行冒泡排序:外层循环控制排序的轮数(i),内层循环控制相邻元素的比较(j)。在内层循环中,比较相邻的元素,如果前一个元素大于后一个元素,则调用swap函数进行交换。

结束时恢复寄存器和栈指针。

打印排序后的数组:同样设置输出格式为字符串,加载"After sort"字符串并存储地址,触发打印。设置输出格式为整数,循环遍历排序后的数组,逐个将元素存储到数据地址,触发打印。

结束程序:使用halt指令停止程序执行。

需要注意的是:

不能将栈指针初始化为0。因为如果将SP设置为0,进行SP - 1操作时,会指向FFFFFFFF,这超出了MIPS模拟器(winmips)的内存范围,可能导致程序崩溃或出现错误。

打印字符串和打印数字时,传递给地址0x10000的值不同,字符串使用4,而数字使用2。这一点需要特别注意,以确保程序能正确显示输出。

2)代码实现

除了lwu,daddi,sd三条指令,还使用如下指令:

  1. dsll :将寄存器中的值左移指定的位数,结果存入目标寄存器。左移时低位补零,适用于乘以2的幂。
  2. bne :如果两个寄存器的值不相等,则跳转到指定标签。常用于条件判断。
  3. jal :跳转到指定标签并保存返回地址到$ra寄存器。常用于调用函数。
  4. slt :比较两个寄存器的值,如果第一个寄存器小于第二个,则将目标寄存器设置为1,否则为0。用于条件判断。
  5. beq :如果两个寄存器的值相等,则跳转到指定标签。与bne相反。
  6. j :无条件跳转到指定标签。用于程序流程控制。
  7. jr :根据寄存器中的地址进行跳转,通常用于返回函数。

    具体实现代码如下:

.data

after: .asciiz "After sort the array is:\n"          # Output after sorting

before: .asciiz "Before sort the array is:\n"        # Output before sorting

CONTROL: .word 0x10000                               # Control address

DATA: .word 0x10008                                  # Data address

SP: .word 0x300                                      # Stack pointer

flag: .word 0                                        # Flag variable

array: .word 9,0,7,2,4,3,1,6,8,5                     # Array to sort

.text

main:

ld r29, SP(r0)                                   # Load stack pointer

    ld r16, CONTROL(r0)                              # Load control address

    ld r17, DATA(r0)                                 # Load data address

    # Print before sorting

    daddi r8, r0, 4                                  # Set string output format

    daddi r9, r0, before                             # Load "Before sort" string

    sd r9, (r17)                                     # Store address for printing

    sd r8, (r16)                                     # Trigger print

    # Print array before sorting

    daddi r8, r0, 2                                  # Set integer output format

    daddi r2, r0, 10                                 # Array length

    daddi r1, r0, 0                                  # Index i

print1:

    dsll r3, r1, 3                                   # Calculate array address

    ld r9, array(r3)                                 # Load array[i]

    sd r9, (r17)                                     # Store for printing

    sd r8, (r16)                                     # Trigger print

    daddi r1, r1, 1                                  # Increment i (i++)

    bne r2, r1, print1                               # Loop if i < 10

    # Sort the array

    daddi r4, r0, array                              # Load array address

    daddi r5, r0, 10                                 # Load length

    jal bubblesort                                   # Call bubble sort

    # Print after sorting

    daddi r8, r0, 4                                  # Set string output format

    daddi r9, r0, after                              # Load "After sort" string

    sd r9, (r17)                                     # Store address for printing

    sd r8, (r16)                                     # Trigger print

    # Print array after sorting

    daddi r8, r0, 2                                  # Set integer output format

    daddi r2, r0, 10                                 # Array length

    daddi r1, r0, 0                                  # Index i

print2:

    dsll r3, r1, 3                                   # Calculate array address

    ld r9, array(r3)                                 # Load array[i]

    sd r9, (r17)                                     # Store for printing

    sd r8, (r16)                                     # Trigger print

    daddi r1, r1, 1                                  # Increment i

    bne r2, r1, print2                               # Loop if i < 10

    halt                                             # End program

bubblesort:

    daddi r29, r29, -24                              # Allocate stack space

    sd $ra, 16(r29)                                  # Save return address

    sd r16, 8(r29)                                   # Save r16

sd r17, 0(r29)                                   # Save r17

    dadd r22, r4, r0                                 # Load array address

    daddi r23, r5, 0                                 # Load length

    # Outer loop: for (int i = 0; i < n; i++)

    and r18, r18, r0                                 # i = 0

loop1:

    slt r10, r18, r23                                # Check i < n

    beq r10, r0, exiti                               # Exit if i >= n

    # Inner loop: for (int j = i - 1; j >= 0; j--)

    daddi r19, r18, -1                               # j = i - 1

loop2:

    slti r10, r19, 0                                 # Check j < 0

    bne r10, r0, exitj                               # Exit if j < 0

    # Compare and swap

    dsll r11, r19, 3                                 # Calculate a[j]

    dadd r12, r11, r22                               # r12 = address of a[j]

    ld r13, 0(r12)                                   # Load a[j]

    ld r14, 8(r12)                                   # Load a[j + 1]

    slt r10, r14, r13                                # Check if a[j + 1] > a[j]

    beq r10, r0, exitj                               # Skip swap if not

    dadd r4, r0, r12                                 # Address of a[j]

    daddi r5, r12, 8                                 # Address of a[j + 1]

    jal swap                                         # Call swap

    # Decrement j and repeat inner loop

    daddi r19, r19, -1                          

    j loop2                                     

exitj:

    # Increment i and repeat outer loop

    daddi r18, r18, 1                            

    j loop1                                     

exiti:

    # Restore stack and return

    ld r17, 0(r29)                                   # Restore r17

    ld r16, 8(r29)                                   # Restore r16

    ld $ra, 16(r29)                                  # Restore return address

    daddi r29, r29, 24                               # Restore stack pointer

    jr $ra                                           # Return to caller

swap:

    # Swap two array elements

    ld r9, 0(r4)                                     # Load a[i]

    ld r10, 0(r5)                                    # Load a[j]

    sd r10, 0(r4)                                    # a[i] = a[j]

    sd r9, 0(r5)                                     # a[j] = a[i]

    jr $ra                                           # Return to caller

3)检查合法性

用asm.exe检验一下程序的正确性,在终端中输入\asm.exe .\sort.s,得到如下的结果,没有错误(0 errors),即sort.s编译非常顺利。

4)结果运行

将sort.s加载到winmips64中,不断地按下F7之后进行单步运行,得到下图的结果。得到cycles顺利地进行了流水执行指令,没有raw stalls的情况发生,然后看终端,可以得到先打印了初始未排序的数组数据9,0,7,2,4,3,1,6,8,5,而后打印了排序后的数组数据0,1,2,3,4,5,6,7,8,9

http://www.khdw.cn/news/68744.html

相关文章:

  • 如何去掉链接wordpressseopeixun com cn
  • 网站统计系统 怎么做爱站工具包手机版
  • 软件工程项目开发的步骤seo优化关键词排名
  • 网站建设需要考虑的问题百度广告收费表
  • 网站建设工作量评估百度网站是什么
  • 哪个网站是免费建站北京营销网站制作
  • 徐汇区网站建设网络销售好做吗
  • 做美食没有广告的网站淘宝关键词搜索
  • 菜谱网站 源码怎么在百度上发布广告
  • 做外贸建网站需要多少钱aso如何优化
  • 嘉兴企业网站搜索引擎优化seo课程总结
  • 可信网站认证必须做吧广东网站优化公司
  • 医院网站建设模板下载深圳网站优化平台
  • wordpress easy smtp桂平seo快速优化软件
  • 品牌建设题目优化设计四年级上册数学答案
  • 广州白云做网站的公司考研培训班集训营
  • 自建网站餐饮服务提供者微信推广平台怎么做
  • 做销售在哪个网站找客户深圳关键词优化平台
  • 做电影网站模板教学设计广州品牌营销服务
  • 好学校平台网站模板下载免费论坛建站系统
  • 大湾区vi设计公司seo关键词是什么
  • 如何提升网站转化率凡科建站代理
  • 网站建设期末作业seo推广排名
  • 泰州网站建设电话百度注册公司地址
  • 广州制作网站报价火爆产品的推广文案
  • 网站标题优化工具同城发广告的平台有哪些
  • 做管道方面的网站app制作公司
  • php与dw怎么做校园网站浙江搜索引擎优化
  • 江苏网站建设价格网络营销前景和现状分析
  • 如何做企业网站的排名全国疫情又严重了