我正在用MIPS编写一个子例程,其中涉及将整数数组和该数组的长度传递给子例程,然后选择排序算法对该数组进行排序,然后打印该数组。
在调试器中逐步跟踪代码时,我很确定我的算法可以正常工作。错误就在这里,它给我一个“数组索引超出范围”的错误:
PRINTL: beq $s3, $a1, RET # i = len -> branch
add $s3, $zero, $zero # i = 0
sll $t0, $s3, 2 # shift i in the array
add $t0, $t0, $s2 # add to base pointer of array
lw $t1, 0($t0) # load ***** ERROR IS HERE *****
add $a0, $zero, $t1 # put address of newl in $a0 to print
addi $v0, $zero, 1 # put 4 in $v0 for printing an int
syscall
j PRINTL
addi $s3, $s3, 1 # i++
j PRINTL # loop
我尝试了很多事情,但无法解决。如果您想自己测试一下,我将在下面发布我的完整代码。也许我的算法无法正常工作,或者我没有将值正确存储到数组中?因为我是MIPS的新手,所以我试图避免使用伪指令,所以我会尽可能地坚持基础知识。任何帮助是极大的赞赏。谢谢
完整代码:
#begin data segment
.data
print: .asciiz "The elements sorted in ascending order are: :"
.align 2 # align data segment
space: .asciiz " " # space to insert between numbers
.align 2
inputs: .space 4 # reserve space for inputs
i: .space 4 # counter variable
arr1: .space 80 # make space for an array up to 100 ints long
# end of data segment
#===========================================================================================
# begin text segment
.text # instruction start here\
MAIN: la $s1, inputs # load address of inputs for use
la $s2, arr1 # load address of arr1
li $v0, 5 # read int -> how many inputs
syscall
add $s1, $v0, $zero # input length -> $s1
addi $s3, $zero, 0 # set i to 0
addi $s7, $s7, 0 # set biggest integer to be 0 for now
# $s0 -> print string
# $s1 -> input length
# $s2 -> arr1 address
# $s3 -> i
# Get all ints
LOOP: slt $t0, $s3, $s1 # i < inputs
beq $t0, $zero, SORT # i >= inputs -> SORT
li $v0,5 # read integer
syscall # System call
add $s0, $v0, $zero # $t1 -> input integer
sll $t0, $s3, 2 # shift i in the array
add $t0, $t0, $s2 # add to base pointer of array
sw $v0, 0($t0) # store into array
addi $s3, $s3, 1 # i++
j LOOP # loop
# $a0 = array | $a1 = len
SORT: add $a0, $s2, $zero
add $a1, $s1, $zero
addi $sp, $sp, -16 # make space on the stack
# s0 = i, s2 = j, s1 = tmp, s3 = minIndex
sw $s0, 0($sp) # store $s0
sw $s1, 4($sp) # store $s1
sw $s2, 8($sp) # store $s2
sw $s3, 12($sp) # store $s3
add $s0, $zero, $zero # i = 0
FOR: addi $t0, $a1, -1 # $t0 = len - 1
slt $t1, $s0, $t0 # i < len - 1
beq $t1, $zero, END # if !(i < len - 1) -> END
add $s3, $zero, $s0 # minIndex = i
FOR2: addi $s2, $s0, 1 # j = i + 1
slt $t2, $s2, $a1 # j < len
beq $t3, $zero, IF # if !(j < len) -> IF to continue parent loop
add $t3, $s3, $a0 # addr. arr[minIndex]
lb $t4, 0($t3) # val. arr[minIndex]
add $t5, $s2, $a0 # addr. arr[j]
lb $t6, 0($t3) # val. arr[j]
slt $t7, $t4, $t5 # arr[minIndex] > arr[j]
beq $t8, $zero, LUP2 # !(arr[minIndex] > arr[j] -> back to loop
add $s3, $zero, $s2 # minIndex = j
addi $s2, $s2, 1 #j++
j LUP2
LUP2: addi $s2, $s2, 1 #j++
j FOR2
IF: beq $s3, $s0, LUP # if minIndex = i -> Loop
add $t2, $s3, $a0 # addr. arr[minIndex]
lb $t3, 0($t2) # val. arr[minIndex] in t3
add $s1, $zero, $t3 # temp = arr[minIndex]
add $t4, $s0, $a0 # addr. arr[i]
lb $t5, 0($t4) # val. arr[i] in t5
add $t2, $zero, $t5 # arr[minIndex] = arr[i]
add $t4, $zero, $s1 # arr[i] = temp
j LUP
LUP: addi $s0, $s0, 1 #i++
j FOR
END: la $s0, print # load the address of string newl
add $a0, $zero, $s0 # put address of newl in $a0 to print
addi $v0, $zero, 4 # put 4 in $v0 for printing a string
syscall
j PRINTL
PRINTL: beq $s3, $a1, RET # i = len -> branch
add $s3, $zero, $zero # i = 0
sll $t0, $s3, 2 # shift i in the array
add $t0, $t0, $s2 # add to base pointer of array
lw $t1, 0($t0) # load
add $a0, $zero, $t1 # put address of newl in $a0 to print
addi $v0, $zero, 1 # put 4 in $v0 for printing an int
syscall
j PRINTL
addi $s3, $s3, 1 # i++
j PRINTL # loop
RET: lw $s0, 0($sp) # restore $s0
lw $s1, 4($sp) # restore $s1
lw $s2, 8($sp) # restore $s2
lw $s3, 12($sp) # restore $s3
addi $sp, $sp, 16 # pop stack
jr $ra