I'm trying to write a simple code which save string and integer input into an array and then prints them (i will also later add another part which sorts them,but i have to get this to work first).
.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
With MARS i get this: line 75: Runtime exception at 0x004000e4: address out of range 0x00000008. The code seems to read correctly, and it prints the first integer i input, and then i get an error when it tries to print the first string. I'm new to mips so the code is probably really bad, and i have some trouble dealing with arrays. What am i doing wrong?
Edit: Thanks to Michael answer i understood what i was doing wrong, but it looks like i don't understand how to do it correctly. I tried adding this code
li $a0, 4
li $v0, 9
syscall #space for new word (4bytes)
move $a0, $v0
li $a1, 4
li $v0, 8
syscall #read name
before the read_string but i still get the same error. How should i do it?
Syscall 8 (read_string
) expects a buffer address in $a0
and a buffer length in $a1
. It does not return anything.
So what you're doing here:
li $v0, 8
syscall #read name
...
sw $v0, 0($s2) #save name
is store the syscall number (8) in your array. And later when you try to print the string, there will be an attempt to print whatever is at address 8, which is why you get the address out of range 0x00000008
error.
You need to allocate some memory for each string. Either statically, in the .data
or .bss
section, or dynamically using the sbrk
syscall. Then for each string, pass the pointer to the correspoing buffer and its length to the read_string
syscall, and store the pointer in your array.