1

我正在尝试编写一个简单的代码,将字符串和整数输入保存到一个数组中,然后打印它们(我稍后还会添加另一个对它们进行排序的部分,但我必须先让它工作)。

.data
array:      .space  40  #10 elements array


in_name:
   .asciiz "\nInsert name: "
in_date:
   .asciiz "\nInsert date (mmdd): "
appt:
   .asciiz "\nList: "
spaz:       .asciiz " "

.text
main:       

    la  $s0, array      #load array in s0
    addi    $t0, $zero, 0       #t0=0 counter
    addi    $s1, $zero, 0       #s1=0 array size counter
            j    Input

Input:
        li  $v0, 4           
    la  $a0, in_date
    syscall             #ask date 
    li  $v0, 5          
    syscall             #read date
    add     $t1, $zero, $t0                #offset in t1
    add     $t1, $t1, $t1           #t1*2
    add     $t1, $t1, $t1           #t1*4
    add     $s2, $t1, $s0           #array with offset in s2
    sw  $v0, 0($s2)     #save date
    addi    $t0, $t0, 1     #t0++
    addi    $s1, $s1, 1     #array size counter +1
    li      $v0, 4
    la      $a0, in_name          
    syscall                         #ask name
    li      $v0, 8
    syscall                         #read name
    add     $t1, $zero, $t0                #offset in t1
    add     $t1, $t1, $t1           #t1*2
    add     $t1, $t1, $t1           #t1*4
    add     $s2, $t1, $s0           #array with offset in s2
    sw  $v0, 0($s2)     #save name
    addi    $s1, $s1, 1     #array size counter +1
    addi    $t0, $t0, 1     #t0++
    beq $s1, 10, print          #if array size=10 go to print
    j   Input               #start over until s1=10



   print:
    la  $a0, appt           
    li  $v0, 4          
    syscall             #print list
    addi    $t0, $zero, 0       #t0=0 counter

res:
    add     $t1, $zero, $t0                #offset in t1
    add     $t1, $t1, $t1           #t1*2
    add     $t1, $t1, $t1           #t1*4
    add     $s2, $t1, $s0           #array with offset in s2
    lw  $a0, 0($s2)     #load date
    li  $v0, 1          
    syscall             #print data
    addi    $t0, $t0, 1             #t0++
    la  $a0, spaz               #load space
    li  $v0, 4          
    syscall             #print space
    add     $t1, $zero, $t0                #offset in t1
    add     $t1, $t1, $t1           #t1*2
    add     $t1, $t1, $t1           #t1*4
    add     $s2, $t1, $s0           #array with offset in s2
    lw  $a0, 0($s2)     #load name
    li      $v0, 4
    syscall                         #print name
    addi    $t0, $t0, 1             #t0++
    la      $a0, spaz             
    syscall                         #print space
    addi    $t0, $t0, 1     #t0++ counter
    bne $t0, $s1, res           #start over until t0=s1
    j   end         
 end:
    li  $v0, 10         
    syscall             #the end

使用 MARS,我得到:第 75 行:0x004000e4 处的运行时异常:地址超出范围 0x00000008。该代码似乎读取正确,它打印了我输入的第一个整数,然后当它尝试打印第一个字符串时出现错误。我是 mips 的新手,所以代码可能真的很糟糕,而且我在处理数组时遇到了一些麻烦。我究竟做错了什么?

编辑:感谢迈克尔的回答,我明白我做错了什么,但看起来我不明白如何正确地做到这一点。我尝试添加此代码

    li      $a0, 4                 
    li      $v0, 9
    syscall                         #space for new word (4bytes)
    move    $a0, $v0
    li      $a1, 4
    li      $v0, 8
    syscall                         #read name

在 read_string 之前,但我仍然得到同样的错误。我该怎么做?

4

2 回答 2

6

系统调用 8( read_string) 需要一个缓冲区地址$a0和一个缓冲区长度$a1。它不返回任何东西。
所以你在这里做什么:

li      $v0, 8
syscall             #read name
...
sw  $v0, 0($s2)     #save name

将系统调用号 (8) 存储在您的阵列中。稍后当您尝试打印字符串时,将尝试打印地址 8 处的任何内容,这就是您收到address out of range 0x00000008错误的原因。

您需要为每个字符串分配一些内存。静态地,在.dataor.bss部分,或者动态地使用sbrk系统调用。然后对于每个字符串,将指向相应缓冲区的指针及其长度传递给read_string系统调用,并将指针存储在数组中。

于 2013-09-15T08:58:00.413 回答
-1

这是你的代码:

li      $a0, 4                  
li      $v0, 9
syscall                         #space for new word (4bytes)
move    $a0, $v0
li      $a1, 4
li      $v0, 8
syscall                         #read name

解决方案是将第一行替换为la $a0, 4

于 2018-10-01T13:57:11.393 回答