簡體   English   中英

MIPS 中的快速排序

[英]QUICKSORT IN MIPS

我根據 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

任何人都可以在此代碼中找到錯誤嗎? 謝謝你的幫助。

  1. 您正在使用保存的寄存器$s0$s1$s2 ,但沒有遵循為調用者保留這些寄存器中的值的要求。

因此, QuickSort的調用者不能保證他們的$s寄存器將被保留。

您沒有顯示代碼的 rest,例如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寄存器保存到 memory 但不使用該 memory 位置的值。

  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寄存器代替這些目的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM