MIPS排序和数组

时间:2010-11-11 21:02:19

标签: assembly mips

我有这个家庭作业问题。我想编写一个执行以下操作的程序:

  1. 将句子中的字母排序为ASCII整理顺序(即按字母顺序排列)。打印结果和句子中的字符总数。
  2. 接下来,打印出句子中每个字母出现次数的列表。
  3. 最后,打印出句子中不同字符的总数。
  4. 当我尝试测试第一个要求时,我没有收到输出字符串。 在接下来的两个方面我也需要帮助。我对MIPS很新,我对它有一些了解,但有一些困难。我从我找到的示例代码中修改了一些代码进行排序。

            .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
    

1 个答案:

答案 0 :(得分:1)

buffer: .space 255

这会用{0}填充buffer

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

我不知道你正在使用什么环境,但这通常与C中的fgets()一样,所以如果你输入hello,你的缓冲区将最终为:

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

之后的代码似乎没有做任何有用的事情:

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

length从未编写过,$t0未被再次使用(直到它被覆盖QS内)。

QS的调用会在$a2中传递固定值(25 - 为什么?)。假设QS例程实际上与广告一样工作:如果原始字符串很短,缓冲区中的一些零字节将包含在已排序的范围内,因此将最终在缓冲区的开头 - 排序的范围将如下所示:

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

即。如果排序的范围包括任何零字节,则结果的第一个字节将为零,因此您将打印一个空字符串。

第2部分:一旦你有一个正确排序的字符串,这应该是直截了当的,因为每个字符的所有出现都是相邻的。只需沿着字符串走,并考虑每个字符是否与前一个字符相同或不同。

第3部分:在完成第2部分的工作时只需要一个额外的计数器。