Reputation: 109
for an assignment in my assembly programming course, I am to multiply two 4x4 matrices and store the result in row-major order and then column-major order. I have coded the functions for the row-major order, but I am not sure why the result isn't being stored in $t7. I also believe that another issue is the jr $ra in rowMulInLoop2 is going back to main rather than it's place in rowMulInLoop1, but again, I am not sure how to fix this issue. I am fairly new to MIPS, but once I am able to figure out this, I should be able to do the column-major on my own. And yes, I have tried debugging but am still confused on how to solve the issues. (P.S. I would like to keep my code as similar to this as possible, unless it's COMPLETELY wrong. Also, I have excluded the functions rowSum and colSum as they are not relevant). Any help would be greatly appreciated. Thanks!
.data
newline: .asciiz "\n"
array1: .word 2,1,9,2
.word 7,9,10,10
.word 3,4,4,4
.word 2,5,4,4
array2: .word 8,7,1,2
.word 2,7,8,6
.word 7,5,6,8
.word 9,4,8,9
rowMulArray: .space 64
size: .word 4
.eqv DATA_SIZE 4
.text
main:
lw $a1, size # size of array stored at $a2
jal rowSum
la $a0, newline
li $v0, 4
syscall
jal rowMul
la $a0, newline
li $v0, 4
syscall
jal colSum
li $v0, 10
syscall
rowMul:
li $t7, 0 # product
li $t0, 0 # row index for product array
li $t1, 0 # column index for product array
move $s0, $zero # row index for array1
move $s1, $zero # column index for array1
move $s2, $zero # row index for array2
move $s3, $zero # column index for array2
rowMulOutLoop:
mul $t2, $t0, $a1
add $t2, $t2, $t1
mul $t2, $t2, DATA_SIZE
rowMulInLoop1:
mul $s4, $s0, $a1
add $s4, $s4, $s1
mul $s4, $s4, DATA_SIZE
mul $s5, $s2, $a1
add $s5, $s5, $s3
mul $s5, $s5, DATA_SIZE
sw $t4, array1($s4)
sw $t5, array2($s5)
mul $t6, $t4, $t5
add $t7, $t7, $t6
addi $t4, $t4, 4
addi $s1, $s1, 1
addi $s2, $s2, 1
bne $s1, $a1, rowMulInLoop1
jal rowMulInLoop2
move $s1, $zero
move $s2, $zero
addi $s0, $s0, 1
addi $s3, $s3, 1
bne $s0, $a1, rowMulInLoop1
rowMulInLoop2:
sw $t7, rowMulArray($t2)
move $a0, $t7
li $v0, 1
syscall
addi $t1, $t1, 1
bne $t1, $a1, rowMulOutLoop
li $t1, 0
addi $t0, $t0, 1
bne $t0, $a1, rowMulOutLoop
jr $ra
jr $ra
Upvotes: 0
Views: 1381
Reputation: 363970
After calculating indices for your source data, you're storing instead of loading.
sw $t4, array1($s4)
sw $t5, array2($s5)
That overwrites your input with garbage, and doesn't update $t4
or $t5
. You probably want lw
.
There might be other bugs, but this is the first obvious one I see, and is a total showstopper. Use your debugger to single-step your code and watch registers change. It should have been obvious that $t4
and $t5
didn't get the right values from the source data at that point.
Also, you should normally avoid the $s
registers because they're call-preserved. main
's caller might crash if you return with them modified. If you run out of other registers, you can save/restore some $s
registers and/or $lr
to use them as scratch, otherwise there's $t0..9
, $v0..1
, and $a0..3
which are all call-clobbered in the normal MIPS calling convention.
Also $at
(the assembler temporary), if you avoid any pseudo-instructions that use it as a temporary when they expand to real MIPS instructions.
Upvotes: 1