创建一个数组并按升序和降序排序[MIPS]

时间:2016-05-10 14:47:56

标签: arrays sorting mips

我必须向用户询问一个号码,存储该号码,然后创建一个该大小的矢量,并要求用户输入存储在阵列中的号码,到目前为止我已经有了这个,但我不知道如何继续:

.data
 string1: .asciiz "\nIntroduce size of array\n"
 string2: .asciiz "\nIntroduce next number\n"
 string3: .asciiz "\nBye\n"

 array: .word

.text
main:   
 la $t4, array       #store the direction of the array

 li $v0, 4
 la $a0, string1
 syscall
 li $v0, 5
 syscall
 move $t0, $v0      #t0 = vector size

 asknum:
 li $v0, 4
 la $a0, string2
 syscall
 li $v0, 5
 syscall
 move $t5, $v0      #t5 = num introduced
 sw $t5, 4($t4)     #save number in the array, the program crashes here
 add $t2, $t2, 1
 bne $t2, $t0, asknum

 la $a0, cadena3
 li $v0,4
 syscall
 li $v0,10
 syscall

我不知道当我尝试存储数字时程序崩溃的原因(我想我存储错误)我真的不知道如何在MIPS语言中对数组进行排序,任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

简单的解决方法是改变:

array: .word

分为:

    .align 4
array: .space 1000

(即)这将允许1000 / 4个数字或250

另一个错误:你永远不会填充array的第一个元素。您正在填充array[1]并且所有值都存储在那里。所以,改变:

sw $t5,4($t4)

分为:

sw $t5,0($t4)
addiu $t4,$t4,4

另一个[次要]错误是你依赖$t2获得零值而不明确设置它。因此,请在asknum:

之前添加
li $t2,0

这是清理过的代码。我添加了对用户数量的限制检查[请原谅无偿风格的清理]:

    .data
string1:    .asciiz     "Introduce size of array: "
string2:    .asciiz     "Introduce next number: "
string3:    .asciiz     "\nBye\n"

    .align  4
array:      .space      1000

    .text

main:
    # prompt user for array size
    li      $v0,4
    la      $a0,string1
    syscall

    li      $v0,5
    syscall
    move    $t0,$v0                 # remember user's count

    li      $t1,250                 # get max size -- user's answer too large?
    bgt     $t0,$t1,main            # yes, ask again

    la      $t4,array               # get the address of the array
    li      $t2,0                   # set index

asknum:
    # prompt user for number
    li      $v0,4
    la      $a0,string2
    syscall

    # get the array value and store it
    li      $v0,5
    syscall
    sw      $v0,0($t4)              # save number in the array

    addi    $t4,$t4,4               # advance array pointer
    addi    $t2,$t2,1               # advance array index
    bne     $t2,$t0,asknum          # more to do? if yes, loop

    la      $a0,string3
    li      $v0,4
    syscall

    li      $v0,10
    syscall

<强>更新

  

你能解释一下如何访问数组的数字吗?我正在尝试使用它打印它们,但它一直打印0:

    li      $s0,0xFFFF0010
    li      $s1,0xFFFF0011
    lw      $t8,4($t4)              # get the first element of the array
    div     $t3,$t8,10

对于数组的简单打印,我不确定此代码如何帮助您。如果没有周围代码的上下文,我很难猜测代码在做什么。

看起来你正在尝试自己做同等的printf("%d",num),但是已经有一个系统调用来向屏幕输出一个整数。我会用那个。但是......如果你真的需要“自己动手”,我已经提供了代码来实现这一目标。

打印数组类似于数组的输入。

我重写了之前的示例代码。数组的输入现在是一个函数。我删除了250的硬连线限制值,转而使用新标签:arrend [所以,看看]

一旦它成为一个函数,将它复制,粘贴并重新编写为打印数组的新函数arrprt是一件简单的事情。

要手动执行syscall 1的操作,我添加了prtint功能。 arrprt将使用系统调用,但如果您希望它使用prtint,请注释掉系统调用并取消注释调用prtint的块

这是新代码:

    .data
msg_siz:    .asciiz     "Introduce size of array: "
msg_num:    .asciiz     "Introduce next number: "
msg_nl:     .asciiz     "\n"
msg_bye:    .asciiz     "\nBye\n"

    .align  4
array:      .space      1000
arrend:

prtint_hex: .asciiz     "0123456789ABCDEF"
prtint_buf: .space      100
    .text

main:
    jal     asknum                  # read in array
    jal     arrprt                  # print array

    # say goodbye
    la      $a0,msg_bye
    li      $v0,4
    syscall

    # exit program
    li      $v0,10
    syscall

# asknum -- read in array of numbers
#
# RETURNS:
#   s0 -- array count
#
# registers:
#   t1 -- maximum array count
#   t2 -- current array index
#   t4 -- array pointer
asknum:
    # prompt user for array size
    li      $v0,4
    la      $a0,msg_siz
    syscall

    # read in user's count
    li      $v0,5
    syscall
    move    $s0,$v0                 # remember user's count

    la      $t4,array               # get address of array

    # get number words of array
    la      $t1,arrend              # get address of array end
    sub     $t1,$t1,$t4             # get array byte length
    srl     $t1,$t1,2               # get array word count

    blez    $s0,asknum              # user's count too small? yes, ask again
    bgt     $s0,$t1,asknum          # user's count too large? yes, ask again

    li      $t2,0                   # set index

    # prompt user for number
asknum_loop:
    li      $v0,4
    la      $a0,msg_num
    syscall

    # get the array value and store it
    li      $v0,5
    syscall
    sw      $v0,0($t4)              # save number in the array

    addi    $t4,$t4,4               # advance array pointer
    addi    $t2,$t2,1               # advance array index
    bne     $t2,$s0,asknum_loop     # more to do? if yes, loop

    jr      $ra                     # return

# arrprt -- print array of numbers
#
# arguments:
#   s0 -- array count
#
# registers:
#   t6 -- current array index
#   t7 -- array pointer
arrprt:
    subiu   $sp,$sp,4
    sw      $ra,0($sp)

    la      $t7,array               # get address of array
    li      $t6,0                   # set index

arrprt_loop:
    # print array value (using syscall)
    lw      $a0,0($t7)              # get array value
    li      $v0,1
    syscall

    # print array value (using prtint)
    ###lw       $a0,0($t7)              # get array value
    ###li       $a1,10                  # get number base to use
    ###jal      prtint

    # output a newline
    li      $v0,4
    la      $a0,msg_nl
    syscall

    addi    $t7,$t7,4               # advance array pointer
    addi    $t6,$t6,1               # advance array index
    bne     $t6,$s0,arrprt_loop     # more to do? if yes, loop

    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra                     # return

# prtint -- print single integer
#
# arguments:
#   a0 -- integer to print
#   a1 -- integer base to use (e.g. 10)
#
# registers:
#   t2 -- current array index
#   t3 -- ascii digits pointer
#   t4 -- buffer pointer
prtint:
    la      $t4,prtint_buf          # get address of scratch buffer
    la      $t3,prtint_hex          # get ascii digits pointer

prtint_loop:
    div     $a0,$a1                 # number / base
    mflo    $a0                     # get next number value
    mfhi    $t1                     # get remainder

    addu    $t1,$t3,$t1             # get address of ascii digit
    lb      $t1,0($t1)              # get ascii digit

    sb      $t1,0($t4)              # store it in buffer
    addiu   $t4,$t4,1               # advance buffer pointer

    bnez    $a0,prtint_loop         # more to do? yes, loop

    sb      $zero,0($t4)            # store EOS

    # NOTE: the buffer we just created is _reversed_ (e.g. for a value of
    # 123, it will be "321"), so we need to reverse it to be useful

    subiu   $t4,$t4,1               # back up to last ascii digit
    la      $t3,prtint_buf          # point to buffer start

prtint_revloop:
    bge     $t3,$t4,prtint_revdone  # are we done? yes, fly

    lb      $t0,0($t3)              # get lhs char
    lb      $t1,0($t4)              # get rhs char

    sb      $t0,0($t4)              # store lhs char
    sb      $t1,0($t3)              # store rhs char

    addiu   $t3,$t3,1               # advance lhs pointer (forward)
    subiu   $t4,$t4,1               # advance rhs pointer (backward)
    j       prtint_revloop

prtint_revdone:
    # get the ascii string value and print it
    la      $a0,prtint_buf
    li      $v0,4
    syscall

    jr      $ra                     # return

答案 1 :(得分:0)

首先当你存储号码然后添加t4和4为下一个号码你没有增加索引u覆盖索引。

第二件事 试试这个

li $ t7,0 阵列($ T7)

就像c,c ++风格