MIPS中的选择排序无法正常工作

时间:2018-10-29 16:43:15

标签: arrays mips selection-sort

我正在用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

0 个答案:

没有答案