📄 matrix_transposition_&_multiplication.asm
字号:
##############################
# Hong Zhang
# Computer Architecture Project
# MIPS
# Matrix Transposition & Multiplication
# Code
##############################
.data
my_info: .asciiz "Hong Zhang\nComputer Architecture Project\nMIPS -- Matrix Transposition & Multiplication\n\n"
strM1: .asciiz "Matrix M1:\n"
strM2: .asciiz "Matrix M2:\n"
strM2tran: .asciiz "Matrix M2tran:\n"
strM3: .asciiz "\nMatrix M3 = M1*M2tran:\n"
newline: .asciiz "\n"
space: .asciiz " "
sys_error: .asciiz "\n!Error!\n"
.align 2
M1: .word 1, 2, 3, 4, 5, 6, 7, 8
M2: .word 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8
M3: .space 128
M2tran: .space 128
R1: .word 4 #rowS of M1
C1: .word 2 #columnS of M1
R2: .word 8 #rowS of M2
C2: .word 2 #columnS of M2
#.align 2
.globl main
.text
main:
# Do the stack stuff
subu $sp, $sp, 64 # allocate new frame
sw $fp, 60($sp) # push the frame pointer
addu $fp, $sp, 64 # update frame pointer
#display my info
la $a0, my_info
li $v0, 4
syscall
##################################
# Display matrix M1
##################################
la $a0, strM1
li $v0, 4
syscall
# prepare aurguments for printing procedure
la $a0 M1 # start of M1 to print
la $t0, R1
lw $t0, 0($t0)
move $a1, $t0 # rows of M1
la $t1, C1
lw $t1, 0($t1)
move $a2, $t1 # column of M1
jal print_array # call printing procedure
###################################
# Display matrix M2
###################################
la $a0, strM2
li $v0, 4
syscall
#prepare aurguments for printing procedure
la $a0 M2 # start of M2 to print
la $t0, R2
lw $t0, 0($t0)
move $a1, $t0 # rows of M2
la $t1, C2
lw $t1, 0($t1)
move $a2, $t1 # column of M2
jal print_array # call printing procedure
####################################
# transpose matrix M2tran
####################################
la $a1, M2tran # Start of array M2tran
la $a2, M2 # Start of array M2
la $t1, R2
lw $t1, 0($t1)
la $t2, C2
lw $t2, 0($t2)
jal matrix_transpose
####################################
# Display matrix M2tran
####################################
la $a0, strM2tran
li $v0, 4
syscall
#prepare aurguments for printing procedure
la $a0, M2tran # start of M2tran to print
la $t0, C2
lw $t0, 0($t0)
move $a1, $t0 # rows of M2tran
la $t1, R2
lw $t1, 0($t1)
move $a2, $t1 # column of M2tran
jal print_array # call printing procedure
####################################
# Calculate matrix M3 = M1 * M2tran
####################################
la $a0, M1 # Start of array M1
la $a1, M2tran # Start of array M2tran
la $a2, M3 # Start of array M3
la $t1, R1
lw $t1, 0($t1) # row of array
la $t2, C1
lw $t2, 0($t2) # column of array
la $t3, R2
lw $t3, 0($t3) # row of array
la $t4, C2
lw $t4, 0($t4) # column of array
jal matrix_multiply
###################################
# Display matrix M3
###################################
la $a0, strM3
li $v0, 4
syscall
#prepare aurguments for printing procedure
la $a0 M3 # start of M3 to print
la $t0, R1
lw $t0, 0($t0)
move $a1, $t0 # rows of M3
la $t1, R2
lw $t1, 0($t1)
move $a2, $t1 # column of M3
jal print_array # call printing procedure
# Do the stack stuff
lw $fp, 60($sp) # pop the frame pointer
addu $sp, $sp, 64 # pop the frame
#syscall to end the program
li $v0, 10
syscall
#####################################################################
# #
# main end #
# #
#####################################################################
###################################
# Procedure to display an array
# $a0 is starting address of the array
# $a1 is the rows of the array
# $a2 is the columns of the array
# Uses $t1 - $t5
###################################
print_array:
# Notice that since this procedure uses no $s registers
# and never calls any other procedures it doesn't have
# to do anything with the stack!
move $t4, $a0 #save the starting address
move $t1, $0 #init i
pa_outerloop:
move $t2, $0 #init j
pa_innerloop:
lw $a0, 0($t4) # read value from array
li $v0, 1
syscall # print the value
la $a0, space # print a blank space
li $v0, 4
syscall
addi $t4, $t4, 4 # move to the next element
addi $t2, $t2, 1 # increment j
# check to see if we should continue the inner loop
blt $t2, $a2, pa_innerloop
###### End inner loop
#print a newline
la $a0, newline
li $v0, 4
syscall
addi $t1, $t1, 1 #increment i
# check to see if we should continue the outer loop
blt $t1, $a1, pa_outerloop
###### End outer loop
jr $ra # return to caller
##################################
# Procedure to transpose a matrix
# $a1 is starting address of the array M2tran
# $a2 is starting address of the array M2
##################################
matrix_transpose:
move $t3, $0 #init i
mt_outerloop:
move $t4, $0 #init j
move $t0, $a2
mt_innerloop:
lw $t5, 0($t0)
sw $t5, 0($a1)
addi $a1, $a1, 4
addi $t0, $t0, 8
addi $t4, $t4, 1 # increment j
# check to see if we should continue the inner loop
blt $t4, $t1, mt_innerloop
###### End inner loop
addi $a2, $a2, 4
addi $t3, $t3, 1 # increment i
# check to see if we should continue the outer loop
blt $t3, $t2, mt_outerloop
###### End outer loop
jr $ra # return to caller
##################################
# Procedure to multiply two matrices
#
##################################
matrix_multiply:
# Do the stack stuff
subu $sp, $sp, 64 # allocate new frame
sw $s0, 60($sp) # push $s0 starting address of B
sw $s1, 56($sp) # push $s1 outer loop counter
sw $s2, 52($sp) # push $s2 inner loop counter
sw $s3, 48($sp) # push $s3 address of row in A
sw $s4, 44($sp) # push $s4 address of column in B
sw $s5, 40($sp) # push $s5 address of element in C
sw $fp, 36($sp) # push the frame pointer
sw $ra, 32($sp) # push the return address
addu $fp, $sp, 64 # update frame pointer
bne $t2, $t4, error # if column of M1 is not equal to row of M2tran
# print an error message and exit
# Calculate matrix M3 = M1 * M2tran
sll $t5, $t2, 2
move $s3, $a0 # init address M1
move $s0, $a1 # init address M2tran
move $s5, $a2 # init address M3
move $s1, $0 # init i
mmult_outer:
move $s2, $0 # init j
move $s4, $s0 # reset M2tran counter to start of M2tran
mmult_inner:
move $a0, $s3 # $a0 = starting address of the row i
move $a1, $s4 # $a1 = starting address of the column j
jal inner_product # find M3[ij]
sw $v0, 0($s5) # store M3[ij]
addi $s5, $s5, 4 # move to next element of M3
addi $s4, $s4, 4 # move to next column of M2tran
addi $s2, $s2, 1 # increment j
# See if we should repeat the inner loop
blt $s2, $t3, mmult_inner
###### End mmult inner loop
add $s3, $s3, $t5 # move to next row of M1
addi $s1, $s1, 1 # increment i
# See if we should repeat the outer loop
blt $s1, $t1, mmult_outer
# Do the stack stuff
lw $s0, 60($sp) # pop $s0
lw $s1, 56($sp) # pop $s1
lw $s2, 52($sp) # pop $s2
lw $s3, 48($sp) # pop $s3
lw $s4, 44($sp) # pop $s4
lw $s5, 40($sp) # pop $s5
lw $fp, 36($sp) # pop the frame pointer
lw $ra, 32($sp) # pop the return address
addu $sp, $sp, 64 # pop the frame
jr $ra # return to caller
##################################
# Procedure to print error message
##################################
error:
# print error message
la $a0, sys_error
li $v0, 4
syscall
# halt the program
li $v0, 10
syscall
##################################
# Procedure to multiplies row of matrix M1 with column of matrix M2tran
# $a0 is the starting address of the row
# $a1 is the starting address of the column
# $v0 is the inner product
##################################
inner_product:
# Do the stack stuff
subu $sp, $sp, 64 # allocate new frame
sw $s0, 60($sp) # push $s0 row address
sw $s1, 56($sp) # push $s1 column address
sw $s2, 52($sp) # push $s2 i
sw $s3, 48($sp) # push $s3 result
sw $fp, 44($sp) # push the frame pointer
sw $ra, 40($sp) # push the return address
addu $fp, $sp, 64 # update frame pointer
# Initializations
sll $t6, $t3, 2
move $s2, $0 # initialize i
move $s3, $0 # initialize the result
move $s0, $a0 # init row address
move $s1, $a1 # init col address
ip_loop:
# load the row and column values
lw $a0, 0($s0) # row value
lw $a1, 0($s1) # col value
# mult the two values
mult $a0, $a1
mflo $v0
add $s3, $s3, $v0 # add product to the result
addi $s0, $s0, 4 # row addr += 4
add $s1, $s1, $t6 # col addr += 4*R2
addi $s2, $s2, 1 # increment i
# Check to see if we should repeat the loop
blt $s2, $t2, ip_loop
##### End ip loop
move $v0, $s3 # send result to caller
# Do the stack stuff
lw $s0, 60($sp) # pop $s0
lw $s1, 56($sp) # pop $s1
lw $s2, 52($sp) # pop $s2
lw $s3, 48($sp) # pop $s3
lw $fp, 44($sp) # pop the frame pointer
lw $ra, 40($sp) # pop the return address
addu $sp, $sp, 64 # pop the frame
jr $ra # return to caller
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -