计算机系统结构实验——两个矩阵相乘

实验内容

(1)编写两个矩阵相乘的程序。
(2)实现多项选择功能(包括循环)。
(3)进一步熟悉运用WinDLX模拟器。
(4)掌握DLX流水线的定向技术、加速比等技术参数,分析读后写停顿周期,进一步掌握调试技术。

实验结果与分析

本程序设计为固定大小的两个矩阵相乘(A为3行4列,B为4行2列)
首先提示A矩阵的大小,按提示输入后会将A矩阵输出,接着提示输入B矩阵
在这里插入图片描述

按提示输入B矩阵后,根据老师要求将B矩阵连续输出两次,接着计算结果并显示出来。提示输入0截至程序运行,输入其他的值继续进行运算。
在这里插入图片描述

如下图输入其他值继续运行
在这里插入图片描述

如下图若输入0,则结束程序
在这里插入图片描述
在这里插入图片描述

实验结果分析:

本次实验主要内容为计算两个矩阵相乘,如上图结果所示能够按老师要求完成实验所有内容,在初次检查时,输入较大的数后,因为显示位数的问题会将结果显示到一起导致无法看清结果,后改进后解决了这个问题,根据老师要求实现输入矩阵A后立即将矩阵A打印出来接着再输入矩阵B,并实现在输出矩阵B时将矩阵B连续输出两次。最后利用循环分支语句实现多次输入矩阵并计算。

程序代码

;********multiply an array to an array*****
;*******    Written by ty   *********
;三个矩阵按行存储
;第一个矩阵的大小为:3*4
;第二个矩阵的大小为:4*2
;存放结果的矩阵大小为:3*2
;l 代表了第一个矩阵的当前被扫描的那行
;r4<=r  相对于result的偏移量
;r5<-l  
;r10<-i  第一个矩阵某一行的某个元素的索引
;r7<-j  第二个矩阵某一列的某个元素的索引
;*******************************************
.data
dat1:        	.space     12
dat2:        	.space     8
result:       	.space     6
Prompt1:     	.asciiz         "Input the martrixA's number:"
Prompt2:     	.asciiz         "Input the martrixB's number:"
Prompt3:     	.asciiz         "Input 0 to end,other continue:"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintfFormat:	.asciiz 	"%7d"	
	        .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
;A 3*4
PrintfFormat5:	.asciiz 	"martrixA is 3*4:\n"
		.align		2
PrintfPar5:	.word		PrintfFormat5
PrintfValue5:	.space		4
;B 4*2
PrintfFormat6:	.asciiz 	"martrixB is 4*2:\n"
		.align		2
PrintfPar6:	.word		PrintfFormat6
PrintfValue6:	.space		4
;
PrintfFormat7:	.asciiz 	"Calculation has been completed!"
		.align		2
PrintfPar7:	.word		PrintfFormat7
PrintfValue7:	.space		4
		.text
		.global main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
main:
  	addi r11,r0,0       ;temp,表示矩阵C的一个元素的累加器
  	addi r4,r0,result        ;r 初始化矩阵C的偏移量
  	addi r5,r0,0        ;l 矩阵A当前被扫描的行号
  	addi r1,r0,3  	
  	movi2fp f1,r1       ;矩阵A的行数
  	addi r1,r0,4
  	movi2fp f2,r1       ;n矩阵A的列数,矩阵B的行数
  	addi r1,r0,2
  	movi2fp f3,r1       ;k矩阵B的列数
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;input A
	movfp2i r8,f1	;将f1转换为整数存入r8
	movfp2i r6,f2	;将f2转换为整数存入r6
	multu   r4,r6,r8     ;计算矩阵A的元素总个数存入r4
	addi    r2,r10,dat1  ;指向A的首地址
	addi	r14,r0,PrintfPar5	;输入提示信息
       	trap    5 
loop1: 	   ;循环输入矩阵A中的元素     
	add     r1,r0,Prompt1   ;矩阵A元素输入提示信息
       	jal	InputUnsigned
       	sb      0(r2),r1        ;将输入的r1存入r2指针位置,储存字节,读入元素
       	addi    r2,r2,1         ;指针地址加1
      	sub     r4,r4,1         ;总的矩阵元素个数r4减一
      	bnez    r4,loop1        ;r4不为0时跳转重复输入
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;output A
	addi    r10,r0,0
	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,inputB   	;矩阵A的行数r8等于0时跳到B1
      	movfp2i r6,f2
       	j       loopA         	;否则继续loopA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
inputB:	                
	movfp2i  r6,f2	;将f2矩阵B行数转换为整数存入r6
       	movfp2i	r12,f3  ;将f3矩阵B列数转换为整数存入r12
       	addi    r10,r0,0		;
       	multu   r4,r6,r12         ;总的矩阵B的元素个数r4
      	addi    r2,r10,dat2       ;指向B的首地址
	addi	r14,r0,PrintfPar6
       	trap    5 
loop2: 
	addi    r1,r0,Prompt2     ;分别读入矩阵B的元素值
       	jal	InputUnsigned
       	sb      0(r2),r1         ;将输入的r1存入r2指针位置,储存字节,读入元素
       	addi    r2,r2,1           ;指针地址加1
       	sub     r4,r4,1           ;总的矩阵元素个数r4减一
       	bnez    r4,loop2 	  ;r4不为0时跳转重复输入	                
       	;addi    r10,r0,0          ;分别读出矩阵B的元素值

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;output B
B1:     
	movfp2i  r6,f2	
	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,B2  ;矩阵B的行数r6等于0时跳到countiu
       	movfp2i r12,f3
       	j       loopB      ;否则继续loopB 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;output B2
B2:     
	movfp2i r12,f3
	addi    r10,r0,0
	movfp2i  r6,f2	
	addi    r2,r10,dat2       ;指向B的首地址
       	sw	PrintfValue3,r1
	    addi	r14,r0,PrintfPar3
       	trap    5
loopB2: 
	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,outputB2   ;矩阵B的列数r12等于0时跳到outputB
      	j      loopB2         ;否则继续loopB               
outputB2: 
	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       loopB2      ;否则继续loopB 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;           
countiue: 
	addi 	r11,r0,0   ;表示矩阵C的一个元素的累加器
       	addi    r4,r0,0    ;初始化矩阵C的偏移量
       	addi    r5,r0,0    ;矩阵A当前被扫描的行号 
line: 
	movi2fp f4,r5       ;判断是否扫描完
  	ltf f4,f1           ;f4>f1跳转(矩阵A的行是否扫描完)  
  	bfpf finish         ;是,则跳转结束程序
  	addi r6,r0,0        ;r6表示当前B矩阵的列号
column: 
	movi2fp f4,r6   
  	ltf f4,f3           ;矩阵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       
       	movfp2i r8,f1	;将矩阵A的行数亦为矩阵C的行数存入r8
       	movfp2i r12,f3	;将矩阵B的列数亦为矩阵C的列数存入r12
       	addi    r2,r10,result	;将r2指向存放结果C的首地址
       	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	;地址加1
       	sub     r12,r12,1	;列数减1
       	beqz    r12,outputC 	;当列数为0跳转outputC,否则继续循环loop3
       	j       loop3                
outputC: 
	sw	PrintfValue1,r1	;换行
	addi	r14,r0,PrintfPar1
       	trap    5
       	sub     r8,r8,1	;将行数减一
       	beqz    r8,end1	;当行数为0则跳转到end1,否则将列数重新传给r12,继续循环loop3
       	movfp2i r12,f3
       	j       loop3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
end1:   
	sw	PrintfValue7,r1
	   addi	r14,r0,PrintfPar7
       	trap    5
	sw	PrintfValue1,r1	;换行
	addi	r14,r0,PrintfPar1
       	trap    5
	add  	r1,r0,Prompt3     ;是否重复
       	jal	InputUnsigned
       	beqz    r1,end2            ;为0则结束运行,否则则重复执行
       	j       main              
end2:
	trap	0

原创出品,如有不足,欢迎指正

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谭你一个脑瓜崩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值