下面是我在MIPS hw任务中的代码,我们必须将两个矩阵相乘。我们的任务是实现matrix_multiply
函数和matrix_print
函数
.data
matrix_a: .word 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
matrix_b: .word 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
result: .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
newline: .asciiz "\n"
tab: .asciiz "\t"
#############################################################################
#############################################################################
## Text segment
#############################################################################
#############################################################################
.text # this is program code
.align 2 # instructions must be on word boundaries
.globl main # main is a global label
.globl multiply
.globl matrix_multiply
.globl matrix_print
.globl matrix_ask
#############################################################################
matrix_ask:
#############################################################################
# Ask the user for the current matrix residing in the $a0 register
sub $sp, $sp, 4
sw $ra, 0($sp)
# init our counter
li $t0, 0
# t1 holds our the address of our matrix
move $t1, $a0
ma_head:
# if counter less than 16, go to ma_body
# else go to exit
li $t2, 16
blt $t0, $t2, ma_body
j ma_exit
ma_body:
# read int
li $v0, 5
syscall
li $t2, 4
# ints are 4 bytes
multu $t0, $t2
mflo $t2
add $t2, $t2, $t1
sw $v0, 0($t2)
j ma_latch
ma_latch:
addi $t0, $t0, 1
j ma_head
ma_exit:
lw $ra, 0($sp)
add $sp, $sp, 4
jr $ra
#############################################################################
main:
#############################################################################
# alloc stack and store $ra
sub $sp, $sp, 4
sw $ra, 0($sp)
# load A, B, and result into arg regs
la $a0, matrix_a
jal matrix_ask
la $a0, matrix_b
jal matrix_ask
la $a0, matrix_a
la $a1, matrix_b
la $a2, result
jal matrix_multiply
la $a0, result
jal matrix_print
# restore $ra, free stack and return
lw $ra, 0($sp)
add $sp, $sp, 4
jr $ra
##############################################################################
multiply:
##############################################################################
# mult subroutine $a0 times $a1 and returns in $v0
# start with $t0 = 0
add $t0,$zero,$zero
mult_loop:
# loop on a1
beq $a1,$zero,mult_eol
add $t0,$t0,$a0
sub $a1,$a1,1
j mult_loop
mult_eol:
# put the result in $v0
add $v0,$t0,$zero
jr $ra
##############################################################################
matrix_multiply:
##############################################################################
# mult matrices A and B together of square size N and store in result.
# alloc stack and store regs
sub $sp, $sp, 24
sw $ra, 0($sp)
sw $a0, 4($sp)
sw $a1, 8($sp)
sw $s0, 12($sp)
sw $s1, 16($sp)
sw $s2, 20($sp)
add $t5, $zero, $zero #Set t5 to zero. i = 0
add $t6, $zero, $zero #Set t6 to zero. j = 0
add $t7, $zero, $zero #Set t7 to zero. k = 0
#setup for i loop
iLoop:
beq $t5, 4, exit
j jLoop
#setup for j loop
jLoop:
beq $t6, 4, iEnd
#setup for k loop
kLoop:
beq $t7, 4, jEnd
# compute A[i][k] address and load into $t3
# A[i][k] = A+4*((4*i) + k)
sll $t3, $t5, 2 # Store 4*i in $t3
addu $t3, $t3, $t7 # Adds $t3 to k
sll $t8, $t3, 2 # Computes 4*($t3) = 4*(4*i+k) by temporarily storing the product in $t8
move $t3, $t8 # Stores 4*($t3) into $t3
addu $t3, $t3, $a0 # Adds A to $t3
lw $t3 0($t3)
# compute B[k][j] address and load into $t4
# B[k][j] = B+4*((4*k) + j)
sll $t4, $t7, 2 # Stores 4*k in $t3
addu $t4, $t4, $t6 # Adds $t4 to j
sll $t8, $t4, 2 # Computes 4*($t4) = 4*(4*k+j) by temporarily storing the product in $t8
move $t4, $t8 # Stores 4*($t4) into $t4
addu $t4, $t4, $a1 # Adds B to $t4
lw $t4 0($t4)
# call the multiply function
multu $t3, $t4
mflo $t9
# compute RESULT[i][j] address and load into $t1
# RESULT[i][j] = RESULT+4*((4*i) + j)
sll $t1, $t5, 2 # Store 4*i in $t1
addu $t1, $t1, $t6 # Adds $t1 to j
sll $t8, $t1, 2 # Computes 4*($t1) = 4*(4*i+k) by temporarily storing the product in $t8
move $t1, $t8 # Stores 4*($t1) into $t1
addu $t1, $t1, $a2 # Adds A to $t3
lw $t1 0($t1)
sw $a2 0($t9) # Store $t9 into its respective location in $a2
# increment k and jump back or exit
addi $t7, $t7, 1
j kLoop
jEnd:
#increment j and jump back or exit
addi $t6, $t6, 1
li $t7, 0
j jLoop
iEnd:
#increment i and jump back or exit
addi $t5, $t5, 1
li $t6, 0
j iLoop
exit:
# retore saved regs from stack
lw $s2, 20($sp)
lw $s1, 16($sp)
lw $s0, 12($sp)
lw $a1, 8($sp)
lw $a0, 4($sp)
lw $ra, 0($sp)
# free stack and return
add $sp, $sp, 24
jr $ra
##############################################################################
matrix_print:
##############################################################################
# alloc stack and store regs.
sub $sp, $sp, 16
sw $ra, 0($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
sw $a0, 12($sp)
li $t0, 4 # size of array
# do your two loops here
# setup to jump back and return
lw $ra, 0($sp)
lw $s0, 4($sp)
lw $s1, 8($sp)
lw $a0, 12($sp)
add $sp, $sp, 16
jr $ra
我不断收到以下两个错误之一 - 我收到错误说Exception occurred at PC=0x004000cc, Arithmetic overflow
或"以下符号未定义"它列出了iEnd,matrix_print,exit和jEnd。我不知道为什么这些符号会被定义为未定义,因为它们已经清楚地写在我的代码中了,而且它们不一定是"全球的"符号,否则matrix_print将不包含在该列表中。
我意识到我还没有实现我的matrix_print
,但是一旦我弄清楚导致更紧迫问题的是什么,这就是我的算术溢出错误。我使用sll
知道我需要乘以4,sll
是接近它的最佳方法。我也不相信我会在任何地方走出界限,所以如果有人可以帮我调试一下,我会非常感激。谢谢!