【问题标题】:Bubble sort algorithm in MIPSMIPS中的冒泡排序算法
【发布时间】:2012-10-23 06:00:38
【问题描述】:

我正在尝试在汇编中编写一个使用冒泡排序算法对数组进行排序的过程,但我遇到了一个问题:

line 22 中,当第一次迭代执行时没有任何问题,程序将array[i+1] 完美地加载到注册器$a1 中,如果交换条件有效,则程序交换没有任何问题。然而,在第二次迭代中,无论元素的实际值是多少,程序总是将0 加载到$a1 中!我尝试调试它,但没有什么清楚的,我不知道这是什么原因。

1.  # Procedure:    bubbleSort
2.  # Objective:    sort an array of integer elements in nondecreasing order
3.  # Input:        an address of an array of integers
4.  # Output:       an array sorted in nondecreasing order
5. 
6.  bubbleSort:
7. 
8.  move    $t0, $a0     # move address of the array into $t0
9.  li      $s0, 1      # boolean swap = false.  0 --> false, 1 --> true
10. li      $t1, 0      # j = 0;
11. li      $t2, 0      # i = 0;
12. li      $s1, 9      # array length
13. loop:
14.     beqz    $s0, exit       # exit if swap = false
15.     li      $s0, 0          # swap = false;
16.     addiu   $t1, $t1, 1  # j++;
17.     move    $t2, $0      # i = 0;
18.     subu    $s2, $s1, $t1  # s2 = length - j
19.     forLoop:
20.         bge     $t2, $s2, exitForLoop   # if i>=s2, exit
21.         lw      $a0, 0($t0)         # a0 = array[i]
22.         lw      $a1, 4($t0)         # a1 = array[i+1]
23.         ble     $a0, $a1, update        # if array[i]<=array[i+1] skip
24.         sw      $a1, 0($t0)         # a[i+1] = a[i]
25.         sw      $a0, 4($t0)         # a[i] = a[i+1]
26.         li      $s0, 1                 # swap = true;
27.         update:
28.         addiu   $t2, $t2, 1         # i++
29.         sll     $t3, $t2, 2         # t3 = i*4
30.         addu    $t0, $t0, $t3        # point to next element -->
31.         j       forLoop
32.     exitForLoop:
33.         j   loop
34. exit:
35.     jr      $ra

【问题讨论】:

    标签: arrays loops assembly mips


    【解决方案1】:

    我刚刚完成了一项具有相同目标的任务;假设用户输入是一个由十个字母组成的字符串,对用户输入进行冒泡排序。我评论了它的废话,所以请随意用作参考。作业还没有评分,我只是希望他们不会因为他们在网上找到这个而认为我作弊。

    ####################################################################################################################################
    #   Data
    ####################################################################################################################################
    .data
    prompt: .asciiz  "\n\nEnter up to 10 characters: "  # Prompt asking for user input
    newLine: .asciiz "\n"                               # Newline character
    theString: .asciiz "           "                    # A ten character string initially filled with whitespace
    
    ####################################################################################################################################
    #   Text
    ####################################################################################################################################
    .text 
    
    ################################################################################################################
    #####   Procedure: Main
    #####   Info:      Asks user for input, gets input, and then call 
    #####              procedures to manipulate the input and output.
    ################################################################################################################
    main:
        ############################################################
        #  Print Prompt
        ############################################################
        la $a0, prompt   # Load address of prompt from memory into $a0
        li $v0, 4        # Load Opcode: 4 (print string) 
        syscall          # Init syscall
    
    
        #############################################
        #  Read User Input into address of theString
        #############################################
        la $a0,theString  # Load address of theString into syscall argument a0
        li $a1,11         # Load sizeOfInput+1 into syscall argument a1
        li $v0,8          # Load Opcode: 8 (Read String)
        syscall
    
        ##############################
        #  Define total num of chars
        ##############################
        li $s7,10           # s7 upper index
    
        ##############################
        #  Call procedures 
        ##############################
        jal uppercase  
        jal sort
        jal print
        j exit
    ################################################################################################################
    ############################################# main END   #######################################################
    ################################################################################################################
    
    
    ################################################################################################################
    #####   Procedure: uppercase
    #####   Info:      Loops through the ten elements of chars gathered from 
    #####              user input and if ascii is in range between 97  
    #####              and 122, it will subtract 32 and store back
    ################################################################################################################
    uppercase:
    
        la $s0, theString    # Load base address to theString into $t0
        add $t6,$zero,$zero  # Set index i = 0 ($t6)
    
    
    
        lupper:
            #####################################
            #  Check for sentinal val and if true
            #  branch to done to jump back to ra
            #####################################
            beq $t6,$s7,done 
    
            #####################################
            #  Load Array[i]
            #####################################
            add $s2,$s0,$t6 #
            lb  $t1,0($s2)
    
            #####################################
            #  if char is within lowercase 
            #  range.
            #####################################
            sgt  $t2,$t1,96
            slti $t3,$t1,123
            and $t3,$t2,$t3
            #####################################
            #  else, don't store byte
            #####################################
            beq $t3,$zero,isUpper
            addi $t1,$t1,-32
            sb   $t1, 0($s2)
    
            isUpper:
            #####################################
            #  increment and Jump back 
            #####################################
            addi $t6,$t6,1
            j lupper
    ################################################################################################################
    ############################################# uppercase END   ##################################################
    ################################################################################################################
    
    
    
    ################################################################################################################
    #####   Procedure: sort
    #####   Info:      Bubble sorts whatever is contained within 
    #####              theString based on ascii values
    ################################################################################################################
    sort:   
        ####################################
        #  Initialize incrementer for outer
        #  loop
        ####################################
        add $t0,$zero,$zero 
    
        ####################################
        #  Outer Loop
        #################################### 
        loop:
            #####################################
            #  Check for sentinal val and if true
            #  branch to done
            #####################################
            beq $t0,$s7,done
    
            ####################################
            #  Initialize upper bound of inner
            #  loop ( 10 - i - 1 ) 
            ####################################
            sub $t7,$s7,$t0
            addi $t7,$t7,-1
    
            ####################################
            #  Initialize incrementer for inner
            #  loop
            ####################################
            add $t1,$zero,$zero
    
            ####################################
            #  Inner Loop
            #################################### 
            jLoop:
                #####################################
                #  Check for sentinal val and if true
                #  branch to continue
                #####################################
                beq $t1,$t7,continue
    
                ####################################
                #  Load Array[i] and Array[i+1]
                ####################################
                add $t6,$s0,$t1
                lb  $s1,0($t6)
                lb  $s2,1($t6)
    
                #########################################
                #  If ascii(Array[i]) > ascii(Array[i+1])
                #  then swap and store
                #########################################
                sgt $t2, $s1,$s2
                #########################################
                #  Else,  don't swap and store
                #########################################
                beq $t2, $zero, good
                sb  $s2,0($t6)
                sb  $s1,1($t6)
    
                good:
                #########################################
                #  increment and Jump back 
                #########################################
                addi $t1,$t1,1
                j jLoop
    
            continue:
            #####################################
            #  increment and Jump back 
            #####################################
            addi $t0,$t0,1
            j loop
    ################################################################################################################
    ############################################# sort END   #######################################################
    ################################################################################################################
    
    
    
    
    ################################################################################################################
    #####   Procedure: Print
    #####   Info:      Prints whatever is stored inside theString
    #####              
    ################################################################################################################
    print:
    
        ####################################
        # Print a new line
        ####################################
        la $a0,newLine
        li $v0,4
        syscall 
    
        ####################################
        #  Initialize incrementer for loop
        ####################################
        add $t6,$zero,$zero # Set index i = 0 $t6
    
        lprint:
            #####################################
            #  Check for sentinal val and if true
            #  branch to done
            #####################################
            beq $t6,$s7,done  
    
            ####################################
            #  Load Array[i] into t1 and print
            ####################################
            add $t1,$s0,$t6 
            lb $a0, 0($t1)  # Load argument
            li $v0, 11      # Load opcode
            syscall         # Call syscall
    
            #########################################
            #  increment and Jump back 
            #########################################
            addi $t6,$t6,1  
            j lprint
    ################################################################################################################
    ############################################# print END   ######################################################
    ################################################################################################################
    
    
    ################################################################################################################    
    #####  Procedure: done
    #####       Info: Jumps to $ra. Only one procedure is needed to jump back to ra
    ################################################################################################################
    
    done:
        jr $ra
    exit:
    

    【讨论】:

      【解决方案2】:

      第 30 行:您正在逐步移动数组并修改数组指针。

      在第一个和所有后续 forloop 之后,您需要在再次执行 forloop 之前重新加载数组的地址,否则它指向错误的位置。

      【讨论】:

        【解决方案3】:

        这是一段 MIPS 中冒泡排序的代码。输入 10 个未排序的数字,这将打印回排序后的数组。希望这会有所帮助:)

        .text
        .globl main
        main:
             la $t1,array
             li $s1,10
        
        L1: beq $s1,$s2,L2
        li $v0,5
        syscall
        sw $v0,0($t1)
        addi $t1,$t1,4
        addi $s2,$s2,1
        j L1
        li $s1,40
        li $s2,0
        li $s3,4
        
        L2: beq $s1,$s2,printf
        add $t1,$t1,$s2
        lw $t0,0($t1)   #a[i]
        L3: beq $s3,$s1,incc
        add $t1,$t1,$s3
        lw $t2,0($t1)   #a[j]
        slt $t3,$t0,$t2
        beq $t3,$0,swap
        L4: addi $s3,$s3,4
        j L3
        
        swap:   
        sw $t0,0($t1)
        sub $t1,$t1,$s2
        sw $t2,0($t1)
        j L4
        
        incc:
        addi $s2,$s2,4
        j L2
        
        
        printf:
        la $t1,array
        li $t0,0
        li $v0,4
        la $a0,print
        syscall
        li $s2,0
        li $s1,10
        L5: beq $s1,$s2,out
        li $v0,1
        lw $t0,0($t1)
        move $a0,$t0
        syscall
        li $v0,4
        la $a0,space
        syscall
        addi $s2,$s2,1
        addi $t1,$t1,4
        j L5
        
        out:
        li $v0,10
        syscall
        .end
        
        .data
        
        array: .word 0,0,0,0,0,0,0,0,0,0
        print: .asciiz "\nthe sorted array : "
        space: .asciiz " "
        

        【讨论】:

          【解决方案4】:

          试试这个冒泡排序。所有行都汇总了 cmets。在 qtspim 上效果很好。

            .data
          arr: .word 10, 60, 40, 70, 20, 30, 90, 100, 0, 80, 50
            space: .asciiz " "
            .text
            .globl main
          
          main:
            lui $s0, 0x1001                   #arr[0]
            li $t0, 0                         #i = 0
            li $t1, 0                         #j = 0
            li $s1, 11                        #n = 11
            li $s2, 11                        #n-i for inner loop
            add $t2, $zero, $s0               #for iterating addr by i
            add $t3, $zero, $s0               #for iterating addr by j
          
            addi $s1, $s1, -1
          
          outer_loop:
            li  $t1, 0                        #j = 0
            addi $s2, $s2, -1                 #decreasing size for inner_loop
            add $t3, $zero, $s0               #resetting addr itr j
          
            inner_loop:
              lw $s3, 0($t3)                  #arr[j]
              addi $t3, $t3, 4                #addr itr j += 4
              lw $s4, 0($t3)                  #arr[j+1]
              addi $t1, $t1, 1                #j++
          
              slt $t4, $s3, $s4               #set $t4 = 1 if $s3 < $s4
              bne $t4, $zero, cond
              swap:
                sw $s3, 0($t3)
                sw $s4, -4($t3)
                lw $s4, 0($t3)
          
              cond:
                bne $t1, $s2, inner_loop      #j != n-i
          
              addi $t0, $t0, 1                  #i++
            bne $t0, $s1, outer_loop           #i != n
          
            li $t0, 0
            addi $s1, $s1, 1
          print_loop:
            li $v0, 1
            lw $a0, 0($t2)
            syscall
            li $v0, 4
            la $a0, space
            syscall
          
            addi $t2, $t2, 4                  #addr itr i += 4
            addi $t0, $t0, 1                  #i++
            bne $t0, $s1, print_loop          #i != n
          
          exit:
            li $v0, 10
            syscall
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-03-19
            • 1970-01-01
            • 2013-09-04
            • 2013-11-02
            • 2018-08-11
            • 2013-07-13
            • 1970-01-01
            • 2016-11-01
            相关资源
            最近更新 更多