我正在尝试编写一个简单的代码,将字符串和整数输入保存到数组中然后打印它们(我稍后还会添加另一个对它们进行排序的部分,但我必须首先使其工作)。
.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之前但我仍然得到相同的错误。我该怎么办?
答案 0 :(得分:4)
Syscall 8(read_string
)期望$a0
中的缓冲区地址和$a1
中的缓冲区长度。它没有返回任何东西。
那你在这里做什么:
li $v0, 8
syscall #read name
...
sw $v0, 0($s2) #save name
将系统调用号(8)存储在数组中。稍后当您尝试打印字符串时,将尝试打印地址8处的任何内容,这就是您收到address out of range 0x00000008
错误的原因。
您需要为每个字符串分配一些内存。静态地,.data
或.bss
部分,或动态使用sbrk
系统调用。然后对于每个字符串,将指针传递给相应的缓冲区,并将其长度传递给read_string
系统调用,并将指针存储在数组中。
答案 1 :(得分:0)
这是您的代码:
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