# $s0 - column number for a matrix # $s1 - row number for a matrix # $s2 - column number for b matrix # $s3 - row number for b matrix # $s4 - column number for c matrix # $s5 - row number for c matrix # all a.m. registers are initialed to ZERO at the 1st use ( see function INIT ) .data matrixA: .word 0:100 matrixB: .word 0:100 matrixC: .align 3 .word 0:100 matrix: .word 0:100 #the tmp matrix which store the input matrixA_float: .align 3 .space 800 #matrix stores the floating point value endl: .asciiz "\n" space: .asciiz " " .text .globl main main: jal init loop: jal menu j choose ################## # # menu # ################## .data title: .asciiz "\nMatrix Calculator\n\n" prompt1: .asciiz " 1. Please enter the positive or negative elements of A matrix.\n" prompt2: .asciiz " 2. Please enter the positive or negative elements of B matrix.\n" prompt3: .asciiz " 3. Perform a + b -> c \n 4. Perform a - b -> c \n 5. Perform a * b -> c \n 6. Perform det( a ) -> c \n 7. Perform transport( a ) -> c " prompt4: .asciiz " \n 8. Move c to a\n 9. Move c to b\n" prompt5: .asciiz " 10. Exit program\n Your choice: " .text menu: li $v0, 4 la $a0, title syscall li $v0, 4 la $a0, prompt1 syscall li $v0, 4 la $a0, prompt2 syscall li $v0, 4 la $a0, prompt3 syscall li $v0, 4 la $a0, prompt4 syscall li $v0, 4 la $a0, prompt5 syscall jr $ra ################## # # Inititial # ################## init: li $s0, 0 # column number for a matrix li $s1, 0 # row number for a matrix li $s2, 0 # column number for b matrix li $s3, 0 # row number for b matrix li $s4, 0 # column number for c matrix li $s5, 0 # row number for c matrix jr $ra ################## # # choose # ################## .data error1: .asciiz "\nError: Wrong choice! \n " .text choose: li $v0, 5 syscall move $t0, $v0 # $t0 is choice number beq $t0, 1, getMatrixA beq $t0, 2, getMatrixB beq $t0, 3, addOp beq $t0, 4, subOp beq $t0, 5, mulOp beq $t0, 6, detOp beq $t0, 7, transOp beq $t0, 8, moveCtoA beq $t0, 9, moveCtoB beq $t0, 10, end li $v0, 4 la $a0, error1 syscall j loop ################## # # genMatrixA -user gives matrix a # ################## .text getMatrixA: li $v0,4 la $a0,prompt1 syscall jal getcol_and_row la $t0, matrix jal getMatrix #the input are stored in tmp matrix move $s0,$t1 move $s1,$t2 #copy tmp matrix to A la $t3,matrix la $t4,matrixA jal copyMatrix li $v0,4 j printMatrixA ################## # # genMatrixB - user gives matrix b # ################## .text getMatrixB: li $v0,4 la $a0,prompt2 syscall jal getcol_and_row la $t0, matrix jal getMatrix move $s2,$t1 move $s3,$t2 #copy tmp matrix to B la $t3,matrix la $t4,matrixB jal copyMatrix j printMatrixB ################## # getcol_and_row # get the number of columns and rows (sharing procedure) # $t1 -- col number # $t2 -- row number ################## .data pmpt: .asciiz "\nPlease enter the number of columns and rows separated by space:\n" char_mes: .asciiz "\nError, non-digit character entered.\n" digit_mes: .asciiz "\nError, no number entered.\n" row_mes: .asciiz "\nError, number of rows is not entered.\n" warning1: .asciiz "\nWarning, the number of rows entered is greater 9, it will be taken as 9.\n" warning2: .asciiz "\nWarning, the number of columns is greater 9, it will be taken as 9.\n" neg_error: .asciiz "\nError, the number of columns or rows should be a positive integer.\n" .text getcol_and_row: sw $31, 0($sp) # save return address add $sp, $sp, -4 li $v0, 4 la $a0, pmpt syscall jal get_integer move $t1, $3 #store the number of columns bgtz $4, check_col #end of line reached after get the first integer bgtz $2, char_error jal get_integer move $t2, $3 #save the number of rows bgtz $4, check_row #end of line reached after get the first integer bgtz $2, char_error j end_get char_error: li $v0, 4 la $a0, char_mes syscall j loop non_digit: li $v0, 4 la $a0, digit_mes syscall j loop no_row: li $v0, 4 la $a0, row_mes syscall j loop check_col: bgtz $2, char_error bgtz $5, no_row j non_digit digit_error: li $v0, 4 la $a0, neg_error syscall j loop check_row: bgtz $2, char_error beqz $5, no_row end_get: blez $t1, digit_error blt $t1, 10, check_rowNumber li $v0, 4 la $a0, warning2 syscall li $t1, 9 check_rowNumber: blez $t2, digit_error blt $t2, 10, return_get #if col number>9, 9 will be assigned li $v0, 4 la $a0, warning1 syscall li $t2, 9 return_get: add $sp, $sp, 4 # restore return address lw $31, 0($sp) jr $31 ################## # printf (called by getMatrix procedure to prompt messages) # print the prompt message for enter the elements in each row # $t1 -- row number (did not change) # $t2 -- col number (did not change) # $t3 -- $t2-$t3 is the row index ($t3 is used in getMatrix as index) ################## .data pmpt1: .asciiz "\nPlease enter " pmpt2: .asciiz " integers for row " pmpt3: .asciiz " :\n" .text printf: sw $31, 0($sp) # save return address add $sp, $sp, -4 li $v0, 4 la $a0,pmpt1 syscall li $v0,1 move $a0,$t1 syscall li $v0,4 la $a0,pmpt2 syscall li $v0,1 sub $a0,$t2,$t3 syscall li $v0,4 la $a0,pmpt3 syscall add $sp, $sp, 4 # restore return address lw $31, 0($sp) jr $31 ################## # getMatrix (sharing procedure) # input matrix element by rows # $t1 -- col number # $t2 -- row number # $t0 -- matrix ################## .data warning3: .asciiz "\nWarning, the number of integers exceed the column number.\n" max_error1: .asciiz "\nError, non-digit character entered.\n" max_error2: .asciiz "\nError, the number of input integers is less than the column number.\n" max_error3: .asciiz "\nError, nothing entered.\n" max_error4: .asciiz "The matrix will not be created or overwrited if existed.\n" .text getMatrix: sw $31, 0($sp) # save return address add $sp, $sp, -4 #t0 holds the matrix address move $t3, $t2 #store row number loop_row: blez $t3,end_getMatrix move $t4, $t1 #col number add $t3,$t3,-1 jal printf loop_col: jal get_integer #get the first one in a row move $t5, $3 add $t4,$t4,-1 bgtz $2, maxError1 beqz $5, maxError2 sw $t5, ($t0) add $t0, $t0, 4 bgtz $4, end_line blez $t4,loop_row j loop_col #when end of line reached, check the numnber of integer entered end_line: bltz $t4,warn bgtz $t4,maxError2 j loop_row warn: li $v0,4 la $a0,warning3 syscall bgtz $4,loop_row discard: jal get_integer beqz $4, discard j loop_row maxError1: li $v0,4 la $a0,max_error1 syscall j maxError maxError2: li $v0,4 la $a0,max_error2 syscall maxError: li $v0,4 la $a0,max_error4 syscall j loop end_getMatrix: add $sp, $sp, 4 # restore return address lw $31, 0($sp) jr $31 ############################################################ # get_integer -- a procedure to form an integer from # a single line of user input # return values: # $2 -- error flag, 0 if there is an error (non-space char) # $3 -- the integer value # $4 -- end of line flag # $5 -- digit flag, 1=yes, 0=no number entered ############################################################ .data ch: .space 2 dig_error: .asciiz "Error: A character is entered." .text get_integer: sw $31, 0($sp) # save return address add $sp, $sp, -4 li $3, 0 # store the integer li $6, 0 # first digit flag ($a2) li $7, 0 # error flag, ($a3) li $s6, 0 # indicate whether the end of line is reached li $s7, 0 #flag for negative number #get the character li $v0,8 la $a0, ch li $a1, 2 get_digit: syscall #loop till the first non-space character lbu $t8, 0($a0) #check the character li $t9, '-' beq $t8, $t9, negative li $t9, '+' beq $t8, $t9, positive li $t9, ' ' beq $t8, $t9, decision li $t9, '\n' beq $t8, $t9, return1 li $t9, '0' blt $t8, $t9, bad_input li $t9, '9' bgt $t8, $t9, bad_input li $t9, 48 # '0' ascii li $6, 1 #it is digit sub $t8, $t8, $t9 #get the integer by sub 48 mul $3, $3, 10 add $3, $3, $t8 j get_digit positive: beqz $6, get_digit j bad_input negative: bgtz $6, bad_input li $s7, 1 j get_digit decision: beqz $6, get_digit #loop till first non-space found j return2 #end of number reached bad_input: li $7, 1 #bad input entered j return2 return1: li $s6, 1 return2: move $2, $7 #error flag (non-digit characters), override $5 move $4, $s6 #end of line reached move $5, $6 #digit flag beqz $s7, return3 sub $3, $0, $3 return3: add $sp, $sp, 4 # restore return address lw $31, 0($sp) jr $31 ################## # # addOp- a+b->c # ################## .data choice3: .asciiz "\nPerform a + b -> c \n " choice4: .asciiz "\nPerform a - b -> c \n " error2: .asciiz " Row not match. Can not do operation! \n" error3: .asciiz " Column not match. Can not do operation! \n" error4: .asciiz " Matrix A is empty entry. Can not do operation! \n " error5: .asciiz " Matrix B is empty entry. Can not do operation! \n" .text addOp: li $v0, 4 la $a0, choice3 syscall jal checkCondition1 whileAddOp: beq $t0, $s5, printMatrixC # outer loop times on row add $t0, $t0, 1 li $t1, 0 # internal loop times on col whileAdd: beq $t1, $s4, whileAddOp lw $t6, ($t3) lw $t7, ($t4) add $t8, $t6, $t7 sw $t8, ($t5) add $t4, $t4, 4 add $t3, $t3, 4 add $t5, $t5, 4 add $t1, $t1, 1 j whileAdd ################## # # subOp- a-b->c # ################## subOp: li $v0, 4 la $a0, choice4 syscall jal checkCondition1 outerLoopSub: beq $t0, $s5, printMatrixC # outer loop times on row add $t0, $t0 1 li $t1, 0 # internal loop times on col interLoopSub: beq $t1, $s4, outerLoopSub lw $t6, ($t3) lw $t7, ($t4) sub $t8, $t6, $t7 sw $t8, ($t5) add $t3, $t3, 4 add $t4, $t4, 4 add $t5, $t5, 4 add $t1, $t1, 1 j interLoopSub # # # # # # # # # shared functions for both Add and Sub Operation # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # checkCondition1: beqz $s0, printError4 # $s0 = 0 ( col = 0 ) matrix a is empty beqz $s1, printError4 # $s1 = 0 ( row = 0 ), matrix a is empty beqz $s2, printError5 # $s2 = 0 ( col = 0 ) matrix b is empty beqz $s3, printError5 # $s3 = 0 ( row = 0 ), matrix b is empty bne $s0, $s2, printError3 # $s0 <> $s2 ( matrix a and b 's column not match ) bne $s1, $s3, printError2 # $s1 <> $s3 ( matrix a and b 's row not match ) move $s4, $s0 # col c = col A move $s5, $s1 # row c = row A li $t0, 0 # loop times by row la $t3, matrixA la $t4, matrixB la $t5, matrixC jr $ra printError2: li $v0, 4 la $a0, error2 syscall j loop printError3: li $v0, 4 la $a0, error3 syscall j loop printError4: li $v0, 4 la $a0, error4 syscall j loop printError5: li $v0, 4 la $a0, error5 syscall ################## # # mulOp- a*b->c # ################## .data choice5: .asciiz "\nPerform a * b -> c \n" error9: .asciiz " The size of Matrix A and Matrix B doesn't match. Can not do multiplication. \n" error10: .asciiz " Matrix A is empty. Can not do multiplication. \n " error11: .asciiz " Matrix B is empty. Can not do multiplication. \n " .text mulOp: li $v0, 4 la $a0, choice5 syscall beqz $s0, printError10 beqz $s1, printError10 beqz $s2, printError11 beqz $s3, printError11 beq $s0, 1, checkConstA # check a constant back: beq $s2, 1, checkConstB # check a constant AmulB: bne $s0, $s3, BmulA # if col of matrix A <> row of matrix B, then check whether we can do B * A la $a1, matrixA # a1 is for multiplicant la $a2, matrixB # a2 is for multiplier move $t0, $s0 # inner loop on matrix A's col move $t1, $s1 # outer loop on matrix A's row move $t2, $s2 # matrix B's col j multiplication BmulA: bne $s1, $s2, printError9 # if col of matrixBA <> row of matrix A, then we can not do mulitplication la $a1, matrixB # a1 is for multiplicant la $a2, matrixA # a2 is for multiplier move $t0, $s2 # inner loop on matrix B's col move $t1, $s3 # outer loop on matrix B's row move $t2, $s0 # matrix A's col j multiplication checkConstA: bne $s1, 1, back j constMulB # matrix A is a const checkConstB: bne $s3, 1, AmulB constMulA: # matix B is a constant move $s5, $s1 # matrix C row = matrix A row move $s4, $s0 # matrix C column = matrix A column la $t0, matrixA la $t9, matrixB # const matrix j constMultiplication constMulB: # matix A is a constant move $s5, $s3 # matrix C row = matrix B row move $s4, $s2 # matrix C column = matrix C column la $t0, matrixB la $t9, matrixA # const matrix j constMultiplication constMultiplication: # a constant * matrix la $t1, matrixC lw $t9, ($t9) # const value mul $t3, $s4, $s5 li $t7, 0 loopConstMul: beq $t7, $t3, printMatrixC lw $t8, ($t0) mul $t8, $t9, $t8 sw $t8, ($t1) add $t0, $t0, 4 add $t1, $t1, 4 add $t7, $t7, 1 j loopConstMul multiplication: la $a3, matrixC move $s5, $t1 # matrix C row move $s4, $t2 # matrix C column li $t3, 0 # outer loop times outerLoopMult: beq $t3, $t1, printMatrixC li $t4, 0 move $t9, $a1 # remember the address of multiplicant at each beginning loop li $t8, 0 # accum. value for each multiply li $t5, 0 # starting element of multiplicator move $t6, $t5 # offset add $t3, 1 innerLoopMult: beq $t4, $t0, store mul $t7, $t6, 4 # $t7 - address for loading multiplicator add $t7, $t7, $a2 lw $s6, ($a1) lw $s7, ($t7) mul $s6, $s6, $s7 add $t8, $t8, $s6 add $a1, 4 add $t6, $t6, $t2 add $t4, 1 j innerLoopMult store: sw $t8, ($a3) add $a3, 4 add $t5, 1 bne $t5, $t2, reinitial j outerLoopMult reinitial: li $t8, 0 move $a1, $t9 li $t4, 0 move $t6, $t5 j innerLoopMult printError9: li $v0, 4 la $a0, error9 syscall j loop printError10: li $v0, 4 la $a0, error10 syscall j loop printError11: li $v0, 4 la $a0, error11 syscall j loop ################## # # detOp- det(a)->c # ################## .data choice6: .asciiz "\nPerform det(a) -> c " error12: .asciiz "\nMatrix A is not square, no valid determinant value. \n" error13: .asciiz "\nDeterminant of matrix A is: 0 \n" msg_det: .asciiz "\nDeterminant of matrix A is: " .text detOp: li $v0, 4 la $a0, choice6 syscall # initialization move $t0, $0 # i move $t1, $0 # j move $t2, $0 # k li.d $f0, 0.0 # ratio li.d $f2, 1.0 # det(A) li.d $f10, 0.0 # comparasion value li.d $f8, -1.0 # check whether A is square bne $s0, $s1, det_a_not_square j det_a_square det_a_not_square: # a is not a square matrix, no valid determinant value li $v0, 4 la $a0, error12 syscall s.d $f0, matrixC j loop det_a_square: la $t3, matrixA #src matrix pointer la $t4, matrixA_float #dest matrix pointer mul $t5, $s0, $s1 #set the number of elements to be copied det_dup_a2af: # copy all the matrix elements to working the matrix of matrixA_float beq $t0, $t5, det_dup_end lw $t7, ($t3) #load the source element mtc1 $t7, $f4 #put into co-processor reg cvt.d.w $f4, $f4 #convert to double s.d $f4, ($t4) #store to destination add $t3, $t3, 4 #increment src matrix pointer add $t4, $t4, 8 #increment dest matrix pointer add $t0, $t0, 1 j det_dup_a2af det_dup_end: move $t0, $0 #clear iterator i det_i_loop: #outmost loop, iterator: $t0, iteration on rows of matrix sub $t3, $s0, 1 beq $t3, $t0, det_i_end #i = 0 ... n-2 move $t3, $t0 #get the address offset of a[i][i] mul $t3, $t3, 8 move $t4, $s0 add $t4, $t4, 1 # $t4 = n + 1 mul $t3, $t3, $t4 #($t3) = i * 8 * n + i * 8 = i * 8 * (n + 1) l.d $f4, matrixA_float($t3) c.eq.d $f4, $f10 bc1t det_find_non_zero j det_swap_end det_find_non_zero: #row number is stored in $t1 move $t1, $t0 mul $t3, $t0, 8 # colum offset add $t1, $t1, 1 # start from row i + 1 to n - 1 mul $t4, $s0, $t1 mul $t4, $t4, 8 add $t4, $t4, $t3 # $t4 = address[x][i] det_nz_loop: beq $t1, $s0, det_zero l.d $f4, matrixA_float($t4) c.eq.d $f4, $f10 bc1f det_swap_row add $t1, $t1, 1 mul $t3, $s0, 8 #$t3 = n * 8 add $t4, $t3, $t4 j det_nz_loop det_swap_row: #beq $t0, $t1, det_swap_end #beq $t1, $s0, det_zero #these two will never be satisfied move $t2, $0 #clear iterator k move $t3, $t0 #row offset for i mul $t3, $t3, 8 mul $t3, $t3, $s0 move $t4, $t1 #row offset for j mul $t4, $t4, 8 mul $t4, $t4, $s0 move $t5, $t2 #colum offset mul $t5, $t5, 8 det_sp_loop: beq $t2, $s0, det_sp_end add $t6, $t5, $t3 add $t7, $t5, $t4 l.d $f4, matrixA_float($t6) l.d $f6, matrixA_float($t7) s.d $f4, matrixA_float($t7) s.d $f6, matrixA_float($t6) add $t2, $t2, 1 add $t5, $t5, 8 j det_sp_loop det_sp_end: mul.d $f2, $f2, $f8 #det *= -1 det_swap_end: move $t1, $t0 add $t1, $t1, 1 # j = i + 1 move $t3, $t0 #get the address offset of a[i][i] mul $t3, $t3, 8 move $t4, $s0 add $t4, $t4, 1 mul $t3, $t3, $t4 #($t3) = i * 8 * (n + 1) l.d $f4, matrixA_float($t3) mul.d $f2, $f2, $f4 #det *= a[i][i] det_j_loop: # beq $t1, $t0, det_k_end # j == i not possible now j = i + 1 ... n - 1 move $t3, $s0 # $t3 = n beq $t1, $t3, det_j_end # j <= n - 1 #calculate the ratio for row j, ratio=a[j][i]/a[i][i] move $t3, $t0 #get the address offset of a[j][i] mul $t3, $t3, 8 move $t4, $t1 mul $t4, $t4, 8 mul $t4, $t4, $s0 add $t4, $t4, $t3 #($t4) = j * n * 8 + i * 8 l.d $f6, matrixA_float($t4) # $f6 = a[j][i] c.eq.d $f6, $f10 bc1t det_j_end # skip the row where a[j][i] == 0 div.d $f0, $f6, $f4 #not necessary to write a[j][i]=0, just leave it there #$f4 currently hold the value of a[i][i] move $t2, $t0 # k = i add $t2, $t2, 1 # k = i + 1 det_k_loop: beq $t2, $s0, det_k_end #k = i + 1 ... n - 1 move $t3, $t2 #get the address offset of a[i][k] mul $t3, $t3, 8 move $t4, $t0 mul $t4, $t4, 8 mul $t4, $t4, $s0 add $t4, $t4, $t3 #($t4) = i * n * 8 + k * 8 l.d $f4, matrixA_float($t4) move $t4, $t1 #get the address offset of a[j][k] mul $t4, $t4, 8 mul $t4, $t4, $s0 add $t4, $t3, $t4 #($t3) = j * n * 8 + k * 8 l.d $f6, matrixA_float($t4) mul.d $f4, $f4, $f0 sub.d $f6, $f6, $f4 s.d $f6, matrixA_float($t4) add $t2, $t2, 1 # k ++ j det_k_loop det_k_end: add $t1, $t1, 1 # j ++ j det_j_loop det_j_end: add $t0, $t0, 1 # i ++ j det_i_loop det_i_end: # end of outmost loop det_end: li $v0, 4 la $a0, msg_det syscall move $t3, $s0 mul $t3, $t3, $t3 # ($t0) = n * n sub $t3, $t3, 1 mul $t3, $t3, 8 l.d $f4, matrixA_float($t3) mul.d $f2, $f2, $f4 add.d $f12, $f2, $f10 # $f12 <- $f10 s.d $f2, matrixC li $v0, 3 #print double syscall j loop det_zero: li $v0, 4 la $a0, error13 syscall j loop ################## # # transOp - a+b ->c # ################## .data choice7: .asciiz "\nPerform transport ( a ) -> c " error8: .asciiz " Matrix Ais empty. Can not do transport A to C \n " .text transOp: li $v0, 4 la $a0, choice7 syscall beqz $s0, printError8 beqz $s1, printError8 la $t0, matrixA la $t1, matrixC move $s4, $s1 # col of matrix c = row of matrix a move $s5, $s0 # rowl of matrix c = col of matrix a li $t2, 0 # outer loop on col # get col by col of matrix a and put them into row by row of matrix c outerLoopTrans: move $t9, $t2 # element index in matrix a beq $t2, $s0, printMatrixC add $t2, $t2, 1 li $t3, 0 # inner loop on row innerLoopTrans: beq $t3, $s1, outerLoopTrans mul $t7, $t9, 4 #mul $t7, $t7, $t0 add $t9 $t9, $s0 # $t3 = $t3 + col # of matrix a add $t3, $t3, 1 lw $t8, matrixA($t7) # load from matrix a sw $t8, ($t1) # store to matrix c add $t1, 4 j innerLoopTrans printError8: li $v0, 4 la $a0, error8 syscall j loop ################## # # moveA - move c to a # ################## .data choice8: .asciiz "\nMove c to a\n" error6: .asciiz " Matrix C is empty entry. Can not move C to A. \n" .text moveCtoA: li $v0, 4 la $a0, choice8 syscall beqz $s4, printError6 # col of matrix c is 0, matrix c is empty beqz $s5, printError6 # row of matrix c is 0, matrix c is empty move $s0, $s4 # col (matrix a ) = col( matrix c ) move $s1, $s5 # row (matrix a ) = row( matrix c ) li $t0, 0 # loop times by row la $t3, matrixC la $t4, matrixA outerLoopMoveA: beq $t0, $s5, printMatrixA # outer loop times on row add $t0, $t0 1 li $t1, 0 # internal loop times on col interLoopMoveA: beq $t1, $s4, outerLoopMoveA jal interLoopMoveAOrB j interLoopMoveA printError6: li $v0, 4 la $a0, error6 syscall j loop ################## # # moveB - move c to b # ################## .data choice9: .asciiz "\nMove c to b\n" error7: .asciiz " Matrix C is empty entry. Can not move C to B. \n" .text moveCtoB: li $v0, 4 la $a0, choice9 syscall beqz $s4, printError7 # col of matrix c is 0, matrix c is empty beqz $s5, printError7 # row of matrix c is 0, matrix c is empty move $s2, $s4 # col (matrix b ) = col( matrix c ) move $s3, $s5 # row (matrix b ) = row( matrix c ) li $t0, 0 # loop times by row la $t3, matrixC la $t4, matrixB outerLoopMoveB: beq $t0, $s5, printMatrixB # outer loop times on row add $t0, $t0 1 li $t1, 0 # internal loop times on col interLoopMoveB: beq $t1, $s4, outerLoopMoveB jal interLoopMoveAOrB j interLoopMoveB printError7: li $v0, 4 la $a0, error7 syscall j loop # # # # # # # # # shared function for Move C to A / B# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # interLoopMoveAOrB: lw $t6, ($t3) # load element of matrix C to register t6 sw $t6, ($t4) # store element of matrix A/B from register t6 add $t3, $t3, 4 add $t4, $t4, 4 add $t1, $t1, 1 jr $ra ################## # # copyMatrix # $t1 -- col number of copyee # $t2 -- row number of copyee # $t3 -- copyee matrix # $t4 -- copier matrix ################## .data copy_error: .asciiz "The source matrix is empty, can not make a copy of it.\n" .text copyMatrix: sw $31, ($sp) #save return address add $sp, $sp, -4 beqz $t1, copyerror # col of copyee is 0 beqz $t2, copyerror # row of copyee is 0 li $t0,0 # $t0 is out loop times (on row) outerLoopCopy: beq $t0, $t2, end_copy # outer loop times on row add $t0, $t0, 1 li $t5, 0 # internal loop times on col interLoopCopy: beq $t5, $t1, outerLoopCopy lw $t6, ($t3) sw $t6, ($t4) add $t3, $t3, 4 add $t4, $t4, 4 add $t5, $t5, 1 j interLoopCopy copyerror: li $v0, 4 la $a0, copy_error syscall j loop end_copy: add $sp,$sp,4 lw $31,($sp) jr $31 ################## # # end # ################## .data bye: .asciiz "\nTerminate program!\n" .text end: li $v0, 4 la $a0, bye syscall li $v0, 10 syscall # # # # # # # # # # shared function in whole program # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # ################## # # print matrix a # ################## .data printA: .asciiz "\nPrint matrix a" .text printMatrixA: li $v0, 4 la $a0, printA syscall li $t0, 0 # outter times on row la $t8, matrixA move $t9, $s1 move $t7, $s0 j printMatricies ################## # # print matrix b # ################## .data printB: .asciiz "\nPrint matrix b" .text printMatrixB: li $v0, 4 la $a0, printB syscall li $t0, 0 # print matrix b outter times on row, la $t8, matrixB move $t9, $s3 move $t7, $s2 j printMatricies ################## # # print matrix c # ################## .data printC: .asciiz "\nPrint matrix c" .text printMatrixC: li $v0, 4 la $a0, printC syscall li $t0, 0 # loop times on col la $t8, matrixC move $t9, $s5 move $t7, $s4 j printMatricies # # # # # # # # # # shared function for print matricies # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # printMatricies: outerLoopPrint: li $v0, 4 la $a0, endl syscall li $t1, 0 # inner loop times on col beq $t0, $t9, loop add $t0, $t0, 1 innerLoopPrint: beq $t1, $t7, outerLoopPrint lw $a0, ($t8) li $v0, 1 syscall li $v0, 4 la $a0, space syscall add $t8, $t8, 4 add $t1, $t1, 1 j innerLoopPrint