6502forlife
6502forlife

Reputation: 11

MIPS sorting and array

I have this homework problem. I'm suppose to write a program that does the following:

  1. Sort the letters in the sentence into the ASCII collating sequence (i.e. alphabetically). Print the results and the total number of characters in the sentence.
  2. Next, print out a list of the number of times each letter occurred in the sentence.
  3. Finally, print out the total number of different characters in the sentence.

When I try to test out the first requirement, I don't receive the output string. I also need help on doing the second two. I'm fairly new to MIPS, and I have some understanding of it, but having some difficulty. I modified some code for the sorting from example code I found.

        .data
length: .word   0
buffer: .space 255
prompt1:.asciiz  "Type in a sentence: "

after:  .asciiz  "\nString  after: "


    .text


# Start of code section

main:
      li       $v0, 4         # Prompt user for a text string
      la       $a0, prompt1      # address of string to print
      syscall
      li       $v0, 8         # Read in text string
      la       $a0, buffer
      li       $a1, 255
      syscall

      la       $t0, buffer    #  Read character from text string
      lw       $t1, length
      addu     $t0, $t0, $t1

# Call on QuickSort

        la      $a0, buffer       # Constant pointer to string

        add     $a1, $a0, 0      # Pointer to left end

        add     $a2, $a0, 25     # Pointer to right end

        jal     QS               # The one call from main

# Print out results

        la      $a0, after

        li      $v0, 4

        syscall

        la      $a0, buffer

        syscall

# End main

        li      $v0, 10

        syscall


QS:     sub     $sp, $sp, 16     # \
        sw      $a1, 0($sp)      #  \

        sw      $a2, 4($sp)      #   > Save registers

        sw      $t2, 8($sp)      #  /  

        sw      $ra, 12($sp)     # / and return address

        bge     $a1, $a2, QSret  # Nothing to sort   

        sub     $t3, $a1, $a0     # index i

        sub     $t4, $a2, $a0     # index j

        add     $t0, $t3, $t4     # t0 = i+j choose middle

        sra     $t0, $t0, 1       # t0 = (i+j) div 2

        add     $t0, $t0, $a0     # t0 -> A[(i+j) div 2]

        lb      $t5, 0($t0)       # t5 = pivot value 

        lb      $t6, 0($a1)       # t6 = A[i] = left element

        sb      $t5, 0($a1)       # Swap them so pivot

        sb      $t6, 0($t0)       # is first element
# 

        move    $t1, $a1         # Initdially i -> first (pivot) item a1

        add     $t2, $a2, 1      # Initially j -> just past last item a2

        lb      $t0, 0($a1)      # Pivot value in t0 (in $t5)

# 
loop:
# 

i_loop: add     $t1, $t1, 1      # i=i+1;

        lb      $t5, 0($t1)      # t5 = A[i]

        bgt     $t0, $t5, i_loop # until pivot <= A[i]

j_loop: sub     $t2, $t2, 1      # j=j-1;

        lb      $t6, 0($t2)      # t6 = A[j]

        blt     $t0, $t6, j_loop # until pivot >= A[j]
#

        bge     $t1, $t2, test   # if i<j swap
#

        sb      $t6, 0($t1)      # A[i] and

        sb      $t5, 0($t2)      # A[j]
#

test:   blt     $t1, $t2, loop   # until i >= j
#

        lb      $t5, 0($a1)      # swap a[a1] = pivot

        lb      $t6, 0($t2)      # and a[j]

        sb      $t5, 0($t2)      # now a[j] is

        sb      $t6, 0($a1)      # in its final position

# Done with partition

        lw      $a1, 0($sp)

        sub     $a2, $t2, 1

        jal     QS               # Recursive call on left

        add     $a1, $t2, 1

        lw      $a2, 4($sp)

        jal     QS               # Recursive call on right
#

QSret:  lw      $ra, 12($sp)     # \Replace return address

        lw      $t2, 8($sp)      #  \

        lw      $a2, 4($sp)      #   > and registers

        lw      $a1, 0($sp)      #  /
        add     $sp, $sp, 16     # /

        jr      $ra

Upvotes: 1

Views: 5445

Answers (1)

Matthew Slattery
Matthew Slattery

Reputation: 46998

buffer: .space 255

This fills buffer with zeroes.

li       $v0, 8         # Read in text string
la       $a0, buffer
li       $a1, 255
syscall

I don't know what environment you're using, but this typically works just like fgets() in C, so if you enter hello, your buffer will end up as:

+-----+-----+-----+-----+-----+-----+-----+-----+   more    +-----+
| 'h' | 'e' | 'l' | 'l' | 'o' |'\n' |  0  |  0  |..zeroes...|  0  |
+-----+-----+-----+-----+-----+-----+-----+-----+           +-----+

The code just after that doesn't seem to do anything useful:

la       $t0, buffer    #  Read character from text string
lw       $t1, length
addu     $t0, $t0, $t1

but length has never been written and $t0 isn't used again (until it's overwritten inside QS).

The call to QS passes a fixed value in $a2 (25 - why?). Assuming that the QS routine actually works as advertised: if your original string is short, some of the zero bytes in the buffer will be included in the range that gets sorted, and so will end up at the beginning of the buffer - the range that gets sorted will look something like this:

+-----+   more    +-----+-----+-----+-----+-----+-----+-----+-----+
|  0  |..zeroes...|  0  |  0  |'\n' | 'e' | 'h' | 'l' | 'l' | 'o' |
+-----+           +-----+-----+-----+-----+-----+-----+-----+-----+

i.e. if the range that gets sorted includes any zero bytes, the first byte of the result will be zero, and so you will print an empty string.

Part 2: once you have a correctly sorted string, this should be straightforward, as all of the occurences of each character are adjacent. Just walk along the string, and consider whether each character is the same as the previous one, or different.

Part 3: just needs an additional counter while doing the work for part 2.

Upvotes: 1

Related Questions