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