0
votes

just like the title states, I am trying to write a program in MIPS assembly that will take a string input by a user of 4 integers between 0-9 separated by spaces and store each of those numbers as an integer into an array. Here's what I have so far:

screen shot of first half

screen shot of second half

.data
input1: asciiz "Input Row 1: "
row1: .asciiz "Row 1: "
array: .space 16
list: .space 8
.text
la $s0, array              #load address of array to s0
li $s1, 0                  #index of array
li $v0, 4                  #call for print string
la $a0, input1             #load string to be printed
syscall
li $v0, 8                  #call for user input
la $a0, list               #address of where the input will be stored
li $a1, 8                  #space allowed for input
syscall
loop:
la $t0, list               #load address of the string
add $t2, $zero, $zero      #index of the string
load:
sll $t3, $t2, 1            #multiply string index by 2 to skip spaces
sll $t4, $s1, 2            #multiply index of array by 4 for size of word
addu $t0, $t0, $t3         #position string
addu $s0, $s0, $t4         #position array
lbu $t1, 0($t0)            #load byte of the string to t1
addiu $t1, $t1, -48        #convert char to integer
sb $t1, 0($s0)             #store byte into the array
addi $t2, $t2, 1           #increment index of string by 1
addi $s1, $s1, 1           #increment index of array by 1
blt $t2, 4, load           #if the index of the string is less than 4, load the next character
li $v0, 11                 #printing first input as integers from here
addi $a0, $zero, 0xA       #new line ascii character
syscall
li $v0, 4                  #call for print string
la $a0, row1               #load string to be printed
syscall
li $v0, 1                  #print integer call
lb $a0, -24($s0)           #load first number input
syscall
li $a0, 32
li $v0, 11                 # syscall number for printing character
syscall
li $v0, 1
lb $a0, -20($s0)           #load second number input
syscall
li $a0, 32
li $v0, 11                 # syscall number for printing character
syscall
li $v0, 1
lb $a0, -16($s0)           #load third number input
syscall
li $a0, 32
li $v0, 11                 # syscall number for printing character
syscall
li $v0, 1
lb $a0, -12($s0)           # load fourth number input
syscall
exit:
li $v0, 10
syscall

The two problems I am having are that I expected the offset of the array to be at -12 (4 words x 4 bytes - 4 for 0 start point), but it starts at -24, and for the 3rd input, no matter what it is, the int 0 gets stored. I am running this program in MARS 4.5. Sample output below:

Input Row 1: 1 2 3 4
Row 1: 1 2 0 4
-- program is finished running --

Eventually I am going to have the user input 4 strings to create a 4x4 matrix and store all of those strings in the same array.

1
One obvious problem is that addu $s0, $s0, $t4 #position array overwrites $s0 so the next loop iteration will not use the correct base address. Use your MARS to single step the program and see what it is doing.Jester
That is used to iterate through the array. Since the first number that is added is 0. It doesn't change the base address. On the second loop, the index is incremented to 1, so that line adds 4, which is the length of a word. I stepped through the program to make sure, and it seems to do what I expect it to do. However, am I not iterating through the array correctly?matt lisec
You are calculating $s1*4 in every iteration, which is correct but should always be added to array. Since you add it to $s0 and you also write it to $s0 it will not work correctly.Jester
But $s0 holds the same address as array. Shouldn't it work the same? I thought that instantiating array in data was just to specify how much space it needed.matt lisec
$s0 only holds array in the first iteration since you do la $s0, array only once at the beginning and you do addu $s0, $s0, $t4 which changes $s0 so it no longer points to array.Jester

1 Answers

2
votes

Jester pointed out to me in the comments what I was doing incorrectly. Instead of incrementing the array address by 4 every time, I was adding 4 more than the last increment. So I was adding 0 the first time, then 4, then 8 to that, putting me at 12, and then 12 more, which is why I ended up at an offset of 24 instead of the expected 12. I moved the declaration of la $s0, array and la $t0, list into the loop, so that it continues to set it back to the base address.

The new loop looks like the following:

loop:
add $t2, $zero, $zero     #index of the string
load: 
la $s0, array              #load address of array to s0
la $t0, list               #load adress of the string
sll $t3, $t2, 1            #multiply string index by 2 to skip spaces
sll $t4, $s1, 2            #multiply index of array by 4 for size of word
addu $t0, $t0, $t3         #position string
addu $s0, $s0, $t4         #position array
lbu $t1, 0($t0)            #load byte of the string to t1
addiu $t1, $t1, -48        #convert char to integer
sb $t1, 0($s0)             #store byte into the array
addi $t2, $t2, 1           #increment index of string by 1
addi $s1, $s1, 1           #increment index of array by 1
blt $t2, 4, load           #if the index of the string is less than 4, load the next character
li $v0, 11                 #printing first input as integers from here
addi $a0, $zero, 0xA
syscall
li $v0, 4                  #call for print string
la $a0, row1               #load string to be printed
syscall
li $v0, 1
lb $a0, -12($s0)
syscall
li $a0, 32
li $v0, 11                 # syscall number for printing character
syscall
li $v0, 1
lb $a0, -8($s0)
syscall
li $a0, 32
li $v0, 11                 # syscall number for printing character
syscall
li $v0, 1
li $a0, 32
li $v0, 11                 # syscall number for printing character
syscall
li $v0, 1
lb $a0, 0($s0)
syscall
exit:
li $v0, 10
syscall

Credit to Jester for steering me in the right direction.