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

Arrays 创建一个数组并按升序和降序对其排序[MIPS],arrays,sorting,mips,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

我必须向用户询问一个数字,存储该数字,然后创建一个该大小的向量,并向用户询问要存储在数组中的数字,到目前为止,我有这个,但我不知道如何继续:

.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语言中对数组进行排序,希望您能提供帮助。

当您存储数字时,首先要做的是将t4与4相加,然后为下一个数字u增加索引u并没有覆盖索引

第二件事 试试这个

李$t7,0 阵列(t7美元)


就像C、C++风格

简单的修复是改变:

array: .word
进入:

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

另一个bug:您从未填充
数组的第一个元素。您正在填充
数组[1]
,所有值都存储在那里。因此,改变:

sw $t5,4($t4)
进入:

另一个[小]错误是,您依赖于
$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:

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

看起来您正在尝试执行自己的等效于
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

您只在
数组中为单个字(即4字节)保留了空间,然后尝试写入
数组+4
(通过
4($t4)
)。不要写入您尚未分配的内存。非常感谢,这非常有用。您能解释一下如何访问数组的编号吗?我试图用这个来打印它们,但它一直在打印0:li$s0,0xFFFF0010 li$s1,0xFFFF0011 lw$t8,4($t4)#获取数组div的第一个元素$t3,$t8,10
    .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
    li      $s0,0xFFFF0010
    li      $s1,0xFFFF0011
    lw      $t8,4($t4)              # get the first element of the array
    div     $t3,$t8,10
    .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