计算机系统结构|虚拟机安装|windlx使用|矩阵相乘实验【保姆级教程】

计算机系统结构|虚拟机安装|windlx教程|矩阵相乘实验

计算机系统结构

计算机系统结构的经典定义为程序员所看到的计算机属性,即概念性结构与功能特性。按照计算机系统的多级层次结构,不同级程序员所看到的计算机具有不同的属性。

在计算机系统结构中有个较为经典的实验:在windlx模拟器下实现矩阵相乘。这篇文章将从头说起,教大家完成矩阵相乘实验。

由于windlx模拟器的古老性,只能在比较古老的系统上使用,而目前许多人的电脑都是win10系统,所以我们需要装个虚拟机,在虚拟机上使用windows xp或者windows7来运行windlx模拟器。

虚拟机安装

这里用的虚拟机为:VMware-workstation. 网盘链接在下面,大家可以直接点进去下载虚拟机。安装也很简单,按照步骤一步一步来即可。

链接:https://pan.baidu.com/s/1HfPZGa8tkrWDYpetp2jTAw
提取码:hnlh

在这里插入图片描述
在安装vm workstation完成之后,需要输入产品序号,直接打开网盘文件中的vm10keygen ,复制上面的serial,此即为产品序号,之后便可正常使用。
在这里插入图片描述
安装vm workstation成功之后,打开界面如下。直接点击打开虚拟机,再装入镜像即可。在这里插入图片描述

windlx使用

在虚拟机安装成功的情况下,便可以在虚拟机中安装windlx模拟器了。windlx模拟器文件在下面:

链接:https://pan.baidu.com/s/1MnerlQl2oxpijvQtU3DYRQ
提取码:bqvq

在虚拟机上安装windlx模拟器十分简单,你可以选择直接将windlx文件拖进虚拟机屏幕内即可。
在这里插入图片描述
打开实验平台文件,直接点击windlx.exe启动即可。
在这里插入图片描述

矩阵相乘实验

在安装完虚拟机与windlx模拟器之后,我们就可以开始矩阵相乘实验啦。
步骤如下:

  • File->reset DLX->确定

在这里插入图片描述

  • File->Load code or data->双击martrix.s->双击input.s->load->是

ATTENTION 此步骤很重要,必须要先点击martrix.s再点击input.s,否则在后面运算的时候会出现wrong address错误。

在这里插入图片描述

  • 接下来就可以直接计算啦!!!
  • execute->run->输入各种数值

下图为最终的计算结果~在这里插入图片描述
在Code窗口中,我们能够看到代表存储器内容的三栏信息,从左到右依次为:地址 (符号或数字)、命令的十六进制机器代码和汇编命令。
在这里插入图片描述
寄存器Rigster图如下:
Register 窗口会显示各个寄存器中的内容。

在这里插入图片描述
在Statistisc中得到结果如下所示
Statistics 窗口提供各个方面的信息:模拟中硬件配置情况、暂停及原因、条件分支、 Load/Store指令、浮点指令和traps。窗口中给出事件发生的次数和百分比.

在这里插入图片描述

流水线PipeLine窗口如下:
下图显示了DLX处理器的五个流水段和浮点操作 (加 / 减, 乘和除)的单元。

在这里插入图片描述

时钟周期Clock Cycle Diagram窗口显示流水线时空图如下:
在这里插入图片描述
好啦!矩阵相乘实验到这里就完成了,最后附上martrix.s文件的代码,想修改代码时可以直接用记事本打开Martrix.s文件直接改即可。

程序代码如下:
;***********multiply an array to an array *************
;***********                     *************
;------------------------------------------------------------------------
; Program begins at symbol main
; requires module INPUT
; Read two arrays, calculate the multiplition of two arrays 
; and write the result to stdout
;------------------------------------------------------------------------ 
.data         
;*** Prompts for input输入提示部分
dat1:        	.space     64
dat2:        	.space     64
result:       	.space     64
Prompt1:	.asciiz 	"Input the martrixA row:"
Prompt2:	.asciiz 	"Input the martrixA column and the martrixB row: "
Prompt3:     	.asciiz         "Input the martrixB column:"
Prompt4:     	.asciiz         "Input the martrixA's number:"
Prompt5:     	.asciiz         "Input the martrixB's number:"
Prompt6:     	.asciiz         "IF you want to run it again (no=0, other continue):"        
;*** Data for printf-Trap        ;输出数据设置部分
PrintfFormat:	.asciiz 	 "%5.3d "
	        .align		2
PrintfPar:	.word		PrintfFormat
PrintfValue: 	.space		4
PrintfFormat1:	.asciiz   	"\n "    
		.align		2
PrintfPar1:	.word		PrintfFormat1
PrintfValue1:	.space		4
PrintfFormat2:	.asciiz   	"Output the martrixA:\n "
		.align		2
PrintfPar2:	.word		PrintfFormat2
PrintfValue2:	.space		4
PrintfFormat3:	.asciiz   	"Output the martrixB:\n "
		.align 		2
PrintfPar3:	.word		PrintfFormat3
PrintfValue3:	.space		4
PrintfFormat4:	.asciiz 	"The result of martrix A*B:\n "
		.align		2
PrintfPar4:	.word		PrintfFormat4
PrintfValue4:	.space		4
		.text
		.global	     main
main: 	addi	r1,r0,Prompt1
	jal	InputUnsigned	
       	movi2fp  f1,r1       ;矩阵A的行数
       	addi	r1,r0,Prompt2
	jal	InputUnsigned	
       	movi2fp f2,r1       ;矩阵A的列数,矩阵B的行数
       	addi    r1,r0,Prompt3
       	jal     InputUnsigned
       	movi2fp	f3,r1       ;矩阵B的列数                
       	movfp2i r8,f1
       	movfp2i r6,f2
      	multu   r4,r6,r8     ;总的矩阵A的元素个数r4
       	addi    r2,r10,dat1  ;指向A的首地址
 loop1: add     r1,r0,Prompt4   ;分别读入矩阵A的元素值
       	jal	InputUnsigned
       	sb      0(r2),r1        ;储存字节,读入元素
       	addi    r2,r2,1         ;元素个数加一
      	sub     r4,r4,1         ;总的矩阵元素个数r4减一
      	bnez    r4,loop1        ;r4不为0时跳转重复输入
        addi    r10,r0,0       ;分别读出矩阵A的元素值
       	addi    r2,r10,dat1     ;指向A的首地址
      	sw	PrintfValue2,r1 
	    addi	r14,r0,PrintfPar2
       	trap    5               
 loopA: lbu     r1,0(r2)       
       	sw	PrintfValue,r1     
	    addi	r14,r0,PrintfPar  ;换行
       	trap    5
       	addi    r2,r2,1         ;元素个数加一
       	sub     r6,r6,1         ;矩阵A的列数r6减一
      	beqz    r6,outputA      ;矩阵A的列数r6等于0时跳到outputA
       	j       loopA          ;否则继续loopA                
outputA: sw	PrintfValue1,r1
	   addi	r14,r0,PrintfPar1
       	trap    5
       	sub     r8,r8,1        ;矩阵A的行数r8减一
       	beqz    r8,countiuB    ;矩阵A的行数r8等于0时跳到countiuB
      	movfp2i r6,f2
       	j       loopA         ;否则继续loopA	                
countiuB: movfp2i  r6,f2
       	movfp2i	r12,f3  
       	addi    r10,r0,0
       	multu   r4,r6,r12         ;总的矩阵B的元素个数r4
      	addi    r2,r10,dat2       ;指向B的首地址
 loop2: addi    r1,r0,Prompt5     ;分别读入矩阵B的元素值
       	jal	InputUnsigned
       	sb      0(r2),r1          ;储存字节,读入元素
       	addi    r2,r2,1           ;元素个数加一
       	sub     r4,r4,1           ;总的矩阵元素个数r4减一
       	bnez    r4,loop2 	  ;r4不为0时跳转重复输入	                
       	addi    r10,r0,0          ;分别读出矩阵B的元素值
       	addi    r2,r10,dat2       ;指向B的首地址
       	sw	PrintfValue3,r1
	    addi	r14,r0,PrintfPar3
       	trap    5
 loopB: lbu     r1,0(r2)
       	sw	PrintfValue,r1
	    addi	r14,r0,PrintfPar   ;换行
       	trap    5
       	addi    r2,r2,1       ;元素个数加一
       	sub     r12,r12,1     ;矩阵B的列数r12减一
       	beqz    r12,outputB   ;矩阵B的列数r12等于0时跳到outputB
      	 j      loopB         ;否则继续loopB               
 outputB: sw	PrintfValue1,r1	
	    addi	r14,r0,PrintfPar1
       	trap    5
       	sub     r6,r6,1     ;矩阵B的行数r6减一
       	beqz    r6,countiue  ;矩阵B的行数r6等于0时跳到countiu
       	movfp2i r12,f3
       	j       loopB      ;否则继续loopB                
 countiue: addi r11,r0,0   ;temp,表示矩阵C的一个元素的累加器
       	addi    r4,r0,0    ;r 初始化矩阵C的偏移量
       	addi    r5,r0,0    ;矩阵A当前被扫描的行号
 line:  movi2fp f4,r5      ;判断是否扫描完
       	ltf     f4,f1      ;f4>f1跳转(矩阵A的行是否扫描完)  
       	bfpf    finish      ;是,则跳转结束程序
       	addi    r6,r0,0     ;col,r6表示当前B矩阵的列号
 column: movi2fp   f4,r6   
       	ltf     f4,f3       ;col(f3)<f4,矩阵B的列是否扫描完
       	bfpf    leveladd    ;是,则跳到矩阵a的下一行  
       	movfp2i r1,f2  
       	multu   r10,r5,r1    ;i<-l*n,r10表示矩阵A当前行的第一个元素的索引
       	addi    r7,r6,0     ;mov col to j(矩阵B某一列的某个元素的索引)
       	addi    r11,r0,0    ;temp=0,矩阵C当前的元素值的初始化
       	addi    r9,r5,1     ;r9<-l+1,r9代表矩阵A当前数组中的实际行号(r5的初值为0)
       	movfp2i r1,f2       ;f2是矩阵A的列数
       	multu   r9,r1,r9     ;p<-n*(l+1),r9代表矩阵A当前行中最后一个元素在数组中的索引
 calculate:movi2fp   f4,r10
       	movi2fp f9,r9
       	ltf     f4,f9    ;compare i to pz(判断是否计算到当前行的最后一个元素)
       	bfpf    asign   ;当前行列相乘完毕,得出结果矩阵C的一个元素(跳转赋值)
       	addi	r1,r10,dat1  ;取矩阵A当前元素在内存区域中的地址
       	lbu	r2,0(r1)    ;从r1所指向的内存单元中取出矩阵A当前的元素暂存在r2
       	addi    r1,r7,dat2   ;取矩阵B当前元素在内存区域中的地址
       	lbu   r3,0(r1)    ;从r1所指向的内存单元中取出矩阵B当前的元素暂存在r3
       	multu   r1,r2,r3     ;temp1<-dat1[i]+dat2[j]
       	add     r11,r11,r1    ;temp<-temp+temp1,累加到累加器
       	addi    r10,r10,1   ;i++,计算矩阵A当前行的下个元素的索引
       	movfp2i r1,f3     
       	add     r7,r7,r1  ;j<-j+k,计算矩阵B的当前列的下个元素的索引
       	j       calculate        
 asign: addi    r1,r4,result    ;r1表示矩阵C当前的地址
       	sb      0(r1),r11      ;store result,把新计算出来的元素放入当前内存单元
       	addi    r4,r4,1        ;赋值完一个元素,偏移量自增1
       	addi    r6,r6,1        ;矩阵B的当前列数自增1
       	j       column         ;矩阵B新的一列开始
 leveladd: addi r5,r5,1        ;矩阵A当前行自增1
       	j       line          ;矩阵A新的一行开始                
 finish: addi   r10,r0,0       ;分别读出矩阵C的元素值
       	movfp2i r8,f1
       	movfp2i r12,f3
       	addi    r2,r10,result
       	sw	PrintfValue4,r1
	    addi	r14,r0,PrintfPar4
       	trap    5               
 loop3: lbu     r1,0(r2)
       sw	PrintfValue,r1
	   addi	r14,r0,PrintfPar
       trap    5
       addi    r2,r2,1
       sub     r12,r12,1
       beqz    r12,outputC 
       j       loop3                
outputC: sw	PrintfValue1,r1
addi	r14,r0,PrintfPar1
       	trap    5
       	sub     r8,r8,1
       	beqz    r8,choice
       	movfp2i r12,f3
       	j       loop3          	  ;*** end
 choice:add  	r1,r0,Prompt6     ;是否重复本次运行操作
       	jal	InputUnsigned
       	beqz    r1,end            ;若为0则结束运行
       	j       main              ;否则则重复执行
 end:   trap	0
``


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值