【问题标题】:QUICKSORT IN MIPSMIPS 中的快速排序
【发布时间】:2020-10-08 05:25:29
【问题描述】:

我已经根据 C++ 代码在 MIPS 汇编中编写了一个快速排序算法。在 C++ 中,它工作得很好,但在 MIPS 中,它不起作用。我调试了它,问题是递归。这是算法:

QuickSort(Data[], l , r)
{
    // If the first index less or equal than the last index
    if l <= r:
    {
        // Create a Key/Pivot Element
        key = Data[r]

        // Create temp Variables to loop through array
        i = l;
        j = r;

        while i <= j:
        {
            while Data[i] < key AND i < r:
                i = i + 1
            while Data[j] > key AND j > 0:
                j = j - 1
            if i <= j:
            {
                swap Data[i], Data[j]
                i = i + 1 
                j = j + 1
            }
        }

        if l < j:
            QuickSort(Data, l, j);
        if r > i:
            QuickSort(Data, i, r);
    }
}

这是 MIPS 代码。它在某些情况下有效。例如:数组 = {6、5、4、3、2、1}。 MIPS 代码:

#-function QuickSort(arr, left,right)
    #parameter
    #          $a0: array
    #          $a1: left
    #          $a2: right

QuickSort:
    subu $sp, $sp, 16
    sw   $a0, 0($sp)
    sw   $a1, 4($sp)
    sw   $a2, 8($sp)
    sw   $ra, 12($sp)

    la   $s0, 0($a0)
    move $s1, $a1
    move $s2, $a2

    bgt  $s1, $s2, done

    sll  $t3, $s2, 2
    add  $t3, $s0,$t3
    lw   $t2, 0($t3)

    move $t0, $s1
    move $t1, $s2

    WhileOuter:
        While_i:
            sll $t3, $t0, 2
            add $t3, $s0, $t3
            lw  $t4, 0($t3)

            bge $t4, $t2, EndWhile_i
            bge $t0, $s2, EndWhile_i
            addi $t0, $t0, 1    
            j While_i
        EndWhile_i:

        While_j:
            sll $t3, $t1, 2
            add $t3, $s0, $t3
            lw $t4, 0($t3)

            ble $t4, $t2, EndWhile_j
            blez $t1, EndWhile_j
            addi $t1, $t1, -1
            j While_j
        EndWhile_j:

        bgt $t0, $t1, EndWhileOuter

        #swap arr[i], arr[j]
        sll $t4, $t0, 2
        sll $t5, $t1, 2

        add $s3, $s0, $t4
        add $s4, $s0, $t5

        lw $t4, 0($s3)
        lw $t5, 0($s4)

        sw $t4, 0($s4)
        sw $t5, 0($s3)

        addi $t0, $t0, 1
        addi $t1, $t1, -1
        j WhileOuter
    EndWhileOuter:

    bge $s1, $t1, call2
    lw $a1, 4($sp)
    move $a2, $t1
    move $a0, $s0
    jal QuickSort

    call2:
    ble $s2, $t0, done
    move $a1, $t0
    lw $a2, 8($sp)
    move $a0, $s0
    jal QuickSort
    done:
    addu $sp, $sp, 16
    lw $a0, 0($sp)
    lw $a1, 4($sp)
    lw $a2, 8($sp)
    lw $ra, 12($sp) 

    jr $ra

谁能找到这段代码中的错误?感谢您的帮助。

【问题讨论】:

    标签: c++ algorithm assembly mips quicksort


    【解决方案1】:
    1. 您正在使用保存的寄存器$s0$s1$s2,但没有遵循为调用者保留这些寄存器中的值的要求。

    因此,QuickSort 的调用者不能保证他们的$s 寄存器会被保留。

    您没有显示其余代码,例如main

    但是,我们知道 QuickSort 会调用自身,并且在第一次递归调用自身之后,它依赖于 $s0$s2 寄存器,这应该没问题,但我们知道它们没有被正确保存QuickSort.

    1. 您需要更仔细地分析您的寄存器使用情况和要求。以下代码在对 QuickSort 的第一次(递归)调用之后运行。它理所当然地期望 $s0$s2 被保留,但也期望 $t0 被保留——这是一个临时寄存器,意味着它不会被调用保留,所以这是一个错误。
            jal QuickSort       # this call wipes out $t0
         call2:
            ble $s2, $t0, done  # what's supposed to be in $t0 here?
            move $a1, $t0
            lw $a2, 8($sp)
            move $a0, $s0
    
    1. 您不需要保存的寄存器$s1,而是应该选择一个临时寄存器用于该用途。我会在其原始$a1 寄存器中使用该变量。

    2. 您正在将 $a0 寄存器保存到内存中,但未使用该内存位置的值。

    3. 它要么丢失,要么您更改了外部 while 循环的退出条件的位置。它不再位于循环的顶部。现在是这样的:

      while true:
            {
                while Data[i] < key AND i < r:
                    i = i + 1
                while Data[j] > key AND j > 0:
                    j = j - 1
                if i > j break;
    
    1. Python 代码可以

          if i <= j:
          {
              swap Data[i], Data[j]
              i = i + 1 
              j = j + 1
          }
      

    而在交换之后汇编代码执行 i++ 而 j-- 。

    1. 您使用的是 $s3$s4,但对于简单的临时用途 - 请改用 $t 寄存器来实现这些目的。

    【讨论】:

    • 我尝试按照您的回答修复我的代码,但它仍然无法正常工作。你能帮我修一下吗?非常感谢!我的代码:github.com/AI005/QuickSortMips.git
    • 更新我的代码正在运行,错误是把恢复堆栈放在恢复寄存器之上。
    猜你喜欢
    • 1970-01-01
    • 2016-08-14
    • 2020-08-14
    • 2014-10-10
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    相关资源
    最近更新 更多