sorting array in mips (assembly)

前端 未结 3 1523
忘了有多久
忘了有多久 2021-01-07 13:25

im in a class learning assembly using mips. I am working on sorting an array of numbers and i think that I have the method working correctly, but just a bit of trouble. I do

相关标签:
3条回答
  • 2021-01-07 14:04

    .data

    value: .word 0x3

    Array: .word 0x14, 0x12, 0x13, 0x05

    .text

    .globl main

    main: la $a0, Array

       lw  $t3,value  
    

    l1: lw $t0, 0($a0)

       lw  $t1, 4($a0)     
    
       blt $t1, $t0, swap   
    
       addi    $a0, $a0, 4
    
       addi $t3,$t3,-1     
    
       bne  $t3,$zero,l1
    
       jr $ra
    

    swap: sw $t0, 4($a0)

        sw  $t1, 0($a0)    
    
        j   l1
    
    0 讨论(0)
  • 2021-01-07 14:12

    This link explains how to print to the screen in a MIPS simulator like QTSPIM or MARS.

    As for the code, there were a few bugs. The line li $a0, 0 is overwriting the work done by the initial la $a0, Array instruction because the li is setting the base address of your array to 0. Instead, you should move the la instruction into the loop so that $a0 is properly reset to the base address of Array after iterating over the entire array, and remove the li instruction. You also will need to add in a condition for when your program has completed the sort. I would suggest the following revisions (tested with SPIM):

    main:
        la  $t0, Array      # Copy the base address of your array into $t1
        add $t0, $t0, 40    # 4 bytes per int * 10 ints = 40 bytes                              
    outterLoop:             # Used to determine when we are done iterating over the Array
        add $t1, $0, $0     # $t1 holds a flag to determine when the list is sorted
        la  $a0, Array      # Set $a0 to the base address of the Array
    innerLoop:                  # The inner loop will iterate over the Array checking if a swap is needed
        lw  $t2, 0($a0)         # sets $t0 to the current element in array
        lw  $t3, 4($a0)         # sets $t1 to the next element in array
        slt $t5, $t2, $t3       # $t5 = 1 if $t0 < $t1
        beq $t5, $0, continue   # if $t5 = 1, then swap them
        add $t1, $0, 1          # if we need to swap, we need to check the list again
        sw  $t2, 4($a0)         # store the greater numbers contents in the higher position in array (swap)
        sw  $t3, 0($a0)         # store the lesser numbers contents in the lower position in array (swap)
    continue:
        addi $a0, $a0, 4            # advance the array to start at the next location from last time
        bne  $a0, $t0, innerLoop    # If $a0 != the end of Array, jump back to innerLoop
        bne  $t1, $0, outterLoop    # $t1 = 1, another pass is needed, jump back to outterLoop
    

    Be sure to check out this link for additional examples and explanations on what each MIPS instruction does.

    0 讨论(0)
  • 2021-01-07 14:12

    Coding direct in assembly is a pain. What I do instead is start with an algorithm (psuedocode or actual code) then translate systematically, as if I am a compiler. I will ignore the input and output stuff and focus on a function that sorts.

    You would call in a high-level lanaguage like C as:

    insertionsort(data, N);
    

    where data is an integer array and N the number of elements (there are no size attributes at machine level).

    Since the function calls nothing, it needs no stack frame. Observe the standard MIPS conventions of using $t registers so you are not trashing anything anyone else relies on and pass in parameters in $a0 and $a1 in that order.

    Step 1: get an algorithm. Here’s one from [Wikipedia][1] for insertion sort:

    i ← 1
    while i < length(A)
        x ← A[i]
        j ← i - 1
        while j >= 0 and A[j] > x
            A[j+1] ← A[j]
            j ← j - 1
        end while
        A[j+1] ← x
        i ← i + 1
    end while
    

    Step 2: paste into a text file, turn all lines into comments and systematically convert to assembly. I use templates for things like loops that take the guess work out of coding (see my free book for examples). I will just give the finished product here; to call it, you need to put the start address of the array into $a0 and its size in $a1, then jal insertionsort:

    # algorithm for insertion sort
    # from https://en.wikipedia.org/wiki/Insertion_sort
    # usage: insertionsort (a,N)
    # pass array start in $a0, size in elements, N in $a1
    # Philip Machanick
    # 30 April 2018
    
                .globl insertionsort
    
                .text
    
    # leaf function, no stack frame needed
    # Registers:
    #   $a0: base address; $a1: N
    #   $t0: i
    #   $t1: j
    #   $t2: value of A[i] or A[j]
    #   $t3: value of x (current A[i])
    #   $t4: current offset of A[i] or A[j] as needed
    insertionsort:
    # i ← 1
           li $t0, 1
    # while i < N
           j Wnext001        # test before 1st iteration
    Wbody001:                # body of loop here
          sll $t4, $t0, 2    # scale index i to offset
          add $t4, $a0, $t4  # address of a[i]
    #     x ← A[i]
          lw $t3, 0($t4)
    #     j ← i - 1
          addi $t1, $t0, -1
    #     while j >= 0 and A[j] > x
           j Wnext002        # test before 1st iteration
    Wbody002:                # body of loop here
    #         A[j+1] ← A[j]
              sll  $t4, $t1, 2        # scale index j to offset
              add $t4, $a0, $t4       # address of a[j]
              lw $t2, 0($t4)          # get value of A[j]
              addi $t4, $t4, 4        # offset of A[j+1]
              sw $t2, 0($t4)          # assign to A[j+1]
    #         j ← j - 1
              addi $t1, $t1, -1
    #     end while
    Wnext002: # construct condition, j >= 0 and A[j] > x
              blt $t1, $zero Wdone002 # convert to: if j < 0 break from loop #####
              sll  $t4, $t1, 2        # scale index j to offset
              add $t4, $a0, $t4       # address of a[j]
              lw $t2, 0($t4)          # A[j]
              bgt $t2, $t3, Wbody002  # no need to test j >= 0, broke from loop already if false
    Wdone002:                         # branch here to short-circuit and
    #     A[j+1] ← x
              add  $t4, $t1, 1        # scale index j+1 to offset
              sll  $t4, $t4, 2        # scale index j to offset
              add $t4, $a0, $t4       # address of a[j+1]
              sw $t3, 0($t4)          # A[j+1] becomes x
    #     i ← i + 1
              addi $t0, $t0, 1
    # end while
    Wnext001: blt $t0,$a1, Wbody001  # i < N easy this time
              jr $ra                 # return to caller
    

    Longer than the other examples – but if you start from an algorithm and translate you are less likely to go wrong. This can go in a separate file if your assembler respects the .globl directive, which makes the name visible in other files.

    [1]: https://en.wikipedia.org/wiki/Insertion_sort – actually from Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford (2001). "Section 2.1: Insertion sort". Introduction to Algorithms (2nd ed.). MIT Press and McGraw-Hill. pp. 15–21

    0 讨论(0)
提交回复
热议问题