.text
.globl main
main:
addi $v0, $0, 4
la $a0, msg_dimensions_matrix
syscall
li $v0, 5 # Scans N (size of matrix).
syscall
move $s7, $v0 # Stores given matrix size in $s7.
addi $v0, $0, 4
la $a0, msg_fill
syscall
addi $t0, $0, 0 # Initializes counter (stored in $t0).
move $a0, $t0 # Moves counter to $a0.
mul $a3, $s7, $s7
mul $a3, $a3, 4
jal input_loop_0 # Calls function input_loop to fill the matrix.
addi $v0, $0, 4
la $a0, msg_dimensions_subm
syscall
li $v0, 5 # Scans M (size of submatrix).
syscall
move $s6, $v0 # Stores submatrix size in $s6.
addi $v0, $0, 4
la $a0, msg_leftdist
syscall
li $v0, 5 # Scans left distance.
syscall
move $s4, $v0 # Stores left distance in $s4.
li $v0, 5 # Scans upper distance.
syscall
move $s5, $v0 # Stores upper distance in $s5.
move $a0, $s5 # Stores upper distance in $a0.
move $a1, $s4 # Stores left distance in $a1.
move $a2, $s6 # Stores submatrix size in $a2.
move $a3, $s7 # Stores matrix size in $a3.
jal submatrix_transpos
j matrix_copy_0
input_loop_0:
addi $v0, $0, 4
la $a0, msg_input
syscall
li $v0, 5
syscall
move $t1, $v0 # Stores user input in $t1.
la $t7, init_matrix
add $t7, $0, $a0
sw $t1, 0($t7) # Stores user input properly in matrix.
addi $a0, $a0, 4 # Increases row counter by 4 bytes.
bne $t7, $a3, input_loop_0 # If row counter is not equal to matrix size, jumps to loop.
jr $ra
submatrix_transpos:
la $t0, init_matrix
mul $t2, $a2, $a0 # M * i
add $t2, $t2, $a1 # (M * i) + j
add $t0, $t0, $t2 # A + ((M * i) + j)
la $t1, submatrix
#addi $t1, $0, $t0 # A + ((M * i) + j)
add $s3, $0, $t0
addi $t4, $0, 0
addi $t7, $0, 4 # $t7 = 4.
mul $s1, $a3, $t7 # Calculates how many bytes each row of the initial matrix has.
mul $t9, $a2, $t7
mul $t5, $s1, $a3
add $s6, $t0, $t5
add $s6, $s6, $t9 # Stores position of bottom right element of submatrix, to be used to break from loop when bounds are reached.
addi $s7, $0, 0 # Number of times loop has been performed set to 0.
submatrix_loop:
lw $t8, init_matrix
sw $t8, submatrix
addi $t1, $t1, 4 # submatrix[j + 1]
add $t0, $t0, $s1 # matrix [i + 1]
addi $t4, $t4, 1 # Increases counter of times i or j is increased, by 1.
beq $t0, $s6, return # If bottom right corner of submatrix is reached, return.
beq $t4, $a2, reset0 # If i or j reaches submatrix bounds, reset accordingly.
j submatrix_loop # Else, then continue.
reset0:
la $t0, init_matrix
add $t0, $0, $s3
la $t1, submatrix
add $t0, $0, $s3
return:
jr $ra
matrix_copy_0:
la $t0, init_matrix # Load address of initial matrix.
la $t1, final_matrix # Load address of final matrix.
addi $t2, $0, 0 # Initialize counter to 0.
addi $t3, $0, 0
add $t4, $s7, $s7 # Size NxN of matrix.
for0:
lw $t3, init_matrix
sw $t3, final_matrix
addi $t2, $t2, 4 # Increase counter by 4 bytes.
addi $t3, $t3, 1
beq $t4, $t3, matrix_copy_1
j for0
matrix_copy_1:
la $t0, final_matrix
mul $t2, $s6, $s5 # M * i
add $t2, $t2, $s4 # (M * i) + j
add $t0, $t0, $t2 # A + ((M * i) + j)
la $t1, submatrix
addi $t8, $0, 0
addi $t3, $0, 0
mul $t7, $s7, 4
for1:
lw $t4, submatrix
sw $t4, final_matrix
addi $t0, $t0, 4
addi $t1, $t1, 4
addi $t8, $0, 1
beq $s6, $t8, reset1
j for1
reset1:
la $t0, final_matrix
mul $t2, $s6, $s5 # M * i
add $t2, $t2, $s4 # (M * i) + j
add $t0, $t0, $t2 # A + ((M * i) + j)
add $t0, $t0, $t7
addi $t3, $t3, 1 # Times in this label increased by one.
beq $t3, $s6, print
j for1
print:
addi $v0, $0, 4
la $a0, msg_final
syscall
la $t0, final_matrix
addi $t1, $0, 0
addi $t4, $0, 0 # Output counter, change line every
addi $t5, $0, 5 # 5 printed integers.
for2:
lw $t3, final_matrix
li $v0, 1 # Print content.
add $a0, $t3, $0
syscall
addi $t0, $t0, 4
addi $t4, $t4, 1
beq $t1, $s7, exit
beq $t4, $t5, reset2
j for2
reset2:
addi $v0, $0, 4
la $a0, newline
syscall
addi $t4, $t4, 0
j for2
exit:
li $v0, 10
syscall
.data
.align 2
init_matrix: .space 400 # Allocates memory for a matrix of size 10*10 maximum, containing integers.
submatrix: .space 400
final_matrix: .space 400
msg_dimensions_matrix: .asciiz "Please define the dimensions of the matrix: \n"
msg_dimensions_subm: .asciiz "Please define the dimensions of the submatrix: \n"
msg_fill: .asciiz "Now, you have to fill the matrix. \n"
msg_input: .asciiz "Please enter an integer: \n"
msg_leftdist: .asciiz "Please define the left distance: \n"
msg_upperdist: .asciiz "Please define the upper distance: \n"
msg_final: .asciiz "The new matrix is: \n"
newline: .asciiz "\n"
我得到:第50行:0x004000c8处的运行时异常:存储地址未在字边界上对齐0x10010533
有人能告诉我为什么会这样吗?是不是“.align 2”应该阻止这个?
答案 0 :(得分:0)
问题是在以下代码中$ a0未设置为0:
input_loop_0:
addi $v0, $0, 4
la $a0, msg_input
syscall
li $v0, 5
syscall
move $t1, $v0 # Stores user input in $t1.
la $t7, init_matrix
add $t7, $0, $a0 <============== $a0 contains the (unaligned) address of msg_input
sw $t1, 0($t7) # Stores user input properly in matrix.
addi $a0, $a0, 4 # Increases row counter by 4 bytes.
bne $t7, $a3, input_loop_0