Click to See Complete Forum and Search --> : need help with arrays


tmanctt
March 6th, 2009, 04:41 PM
I'm pretty new to MIPS assembly language and I am having a problem using arrays. I am trying to store integers in an array that are user entered and then print the array. I also need to print the array in reverse order as well.

this is what I have so far, it stores the integers in the array just fine but wont print the array correctly.

#print array and also print in reverse

.data
.align 2

numArray: .space 40

.text
.globl main

main:
li $t1, 1
la $s0, numArray

while: bgt $t1, 10, endwhile
li $v0, 5
syscall

sw $v0, 0($s0)
addi $t1, $t1, 1
addi $s0, $s0, 4
j while

endwhile:

jal printArray

printArray:

li $s0, 1
la $a0, numArray
syscall

jr $ra

li $v0, 10
syscall
# end program

rxbagain
March 6th, 2009, 05:41 PM
Here's the fixed code.
.data
.align 2

numArray: .space 40
space: .asciiz " "

.text
.globl main

main:
li $t1, 1
la $s0, numArray

while: bgt $t1, 10, endwhile
li $v0, 5
syscall

sw $v0, 0($s0)
addi $t1, $t1, 1
addi $s0, $s0, 4
j while

endwhile:

# at this point, the value of t1 is 11, and s0 is at the end of the array
# to print in reverse, we can iterate backward while printing the data
# we dont need to setup the value of t1 & s0 since we already have them

_print_all:
addi $t1, $t1, -1 # subtract 1 to our counter
addi $s0, $s0, -4 # adjust the pointer backward

li $v0, 1 # use print_int
lw $a0, 0($s0) # get the value pointed by s0
syscall # print it

li $v0, 4 # we print space between each output
la $a0, space
syscall

bgt $t1, 1, _print_all # if still greater than 1, continue _print_all

li $v0, 10
syscall
# end program
Hope it will help :)

tmanctt
March 6th, 2009, 06:06 PM
thank you that helps a lot!

now i need to print them out in the order that they were entered

I have tried this code

printArray:

addi $t1, $t1, -1 # subtract 1 to our counter
addi $s0, $s0, -4 # adjust the pointer backward

li $v0, 1
lw $a0, numArray #print numArray
syscall

li $v0, 4 #print space
la $a0, revSpace
syscall


All i am getting is the first number that was entered in the array and then it goes to the reverse print function

rxbagain
March 6th, 2009, 06:16 PM
u'r welcome :)

to print in order, you can do the same way as your first loop but this time, it
would be printing the output.

rxbagain
March 7th, 2009, 01:27 PM
Hi tmanctt,

I'm sorry i did not notice you edited your post.

You can only print the first input because you did not use the pointer variable (s0) in loading the value. You directly trying to load from numArray (lw $a0, numArray #print numArray) and there is no loop to count from 1 to 10 and adjust the pointer

You must be thinking that when you print from the start of the array, it will print all the array contents. It's not as simple as that. You have to iterate through the elements and print them one by one.

Here is my modified code. You can notice that I simply got the iteration from you code (from main to endwhile) #print array and also print in reverse

.data
.align 2

numArray: .space 40
space: .asciiz " "

.text
.globl main

main:
li $t1, 1
la $s0, numArray

while: bgt $t1, 10, endwhile
li $v0, 5
syscall

sw $v0, 0($s0)
addi $t1, $t1, 1
addi $s0, $s0, 4
j while

endwhile:

# to print the array in normal order, we reinitialize the counter/pointer

li $t1, 1
la $s0, numArray

print_while: bgt $t1, 10, print_endwhile
# li $v0, 5
li $v0, 1 # use print_int
lw $a0, 0($s0) # get the value pointed by s0
syscall

li $v0, 4 # we print space between each output
la $a0, space
syscall

# sw $v0, 0($s0)
addi $t1, $t1, 1
addi $s0, $s0, 4

j print_while

print_endwhile:


# at this point, the value of t1 is 1, and s0 is at the end of the array
# to print in reverse, we can iterate backward while printing the data
# we dont need to setup the value of t1 & s0 since we already have them

_print_all:
addi $t1, $t1, -1 # subtract 1 to our counter
addi $s0, $s0, -4 # adjust the pointer backward

li $v0, 1 # use print_int
lw $a0, 0($s0) # get the value pointed by s0
syscall # print it

li $v0, 4 # we print space between each output
la $a0, space
syscall

bgt $t1, 1, _print_all # if still greater than 1, continue _print_all

li $v0, 10
syscall
# end program

tmanctt
March 8th, 2009, 01:40 AM
Thank you for all your help, I have one last question.

Is there a new line statement in assembly so that the output for printing the array normally and in reverse are on different lines and not the same?

rxbagain
March 8th, 2009, 01:51 AM
If you want them in separate lines, simply print a string (syscall 4) with line feed ('\n') character...

newline: .asciiz "\n"

#print in normal sequence

li $v0, 4
la $a0, newline
syscall

#print in reversed sequence

tmanctt
March 9th, 2009, 06:19 PM
Thank you for all your help with this.

How would the code change if i wanted to make the array print in reverse recursively instead of iteratively?

here is what i have so far but it doesn't print anything when i run the program.


revPrintArray:

lb $t1, 0($s0)

bne $t0, $zero, else

else:

addi $sp, $sp, -8
sw $ra, 0($sp)
sw $t0, 4($sp)

addi $a0, $a0, 1
jal revPrintArray

lw $ra, 0($sp)
lw $a0, 4($sp)
addi $sp, $sp, 8

li $v0, 1
syscall

li $v0, 4
la $a0, space
syscall

rxbagain
March 10th, 2009, 01:30 AM
Going back to our code, I just made some modification.

I only preserved the return address address since s0 and t1 values are always valid within the function. I also used same criteria (using t1 register) to decide whether to do recursive call or to end the function.
.data
.align 2

numArray: .space 40
space: .asciiz " "
newline: .asciiz "\n"

.text
.globl main

main:
li $t1, 1
la $s0, numArray

while: bgt $t1, 10, endwhile
li $v0, 5
syscall

sw $v0, 0($s0)
addi $t1, $t1, 1
addi $s0, $s0, 4
j while

endwhile:

# to print the array in normal order, we reinitialize the counter/pointer

li $t1, 1
la $s0, numArray

print_while: bgt $t1, 10, print_endwhile
# li $v0, 5
li $v0, 1 # use print_int
lw $a0, 0($s0) # get the value pointed by s0
syscall

li $v0, 4 # we print space between each output
la $a0, space
syscall

# sw $v0, 0($s0)
addi $t1, $t1, 1
addi $s0, $s0, 4

j print_while

print_endwhile:

li $v0, 4
la $a0, newline
syscall

# at this point, the value of t1 is 1, and s0 is at the end of the array
# to print in reverse, we can iterate backward while printing the data
# we dont need to setup the value of t1 & s0 since we already have them

jal _print_all

li $v0, 10
syscall

_print_all:

addi, $sp, $sp, -4 # prepare the stack (for return address storage)
sw $ra, ($sp) # save return address on the stack space

addi $t1, $t1, -1 # subtract 1 to our counter
addi $s0, $s0, -4 # adjust the pointer backward

li $v0, 1 # use print_int
lw $a0, 0($s0) # get the value pointed by s0
syscall # print it

li $v0, 4 # we print space between each output
la $a0, space
syscall

# bgt $t1, 1, _print_all # if still greater than 1, continue _print_all
ble $t1, 1, _print_all_exit # if t1 <= 1, exit sub

jal _print_all # else call recursively

_print_all_exit:
lw $ra, ($sp) # retrieve the return address from the stack
addi, $sp, $sp, 4 # and fix the stack pointer
jr $ra # RETURN

# end program