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 を初めて使用するので、コードはおそらく本当に悪いものであり、配列の処理に問題があります。私は何を間違っていますか?

編集:Michael answerのおかげで、私が間違っていたことを理解しましたが、正しく行う方法を理解していないようです。このコードを追加してみました

    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

Syscall 8( read_string) は、バッファ アドレス in$a0とバッファ長 in を想定してい$a1ます。何も返しません。
だからあなたはここで何をしているのか:

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

syscall 番号 (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 に答える