Trying to change array value in MIPS assembly - arrays

I was hoping that I could get some help debugging some code. I am going to try to not make this a It is for a MIPS assembly project in recursion. The program is only supposed to print prime numbers.
The idea is I have two arrays, one that lists every whole number up to 110, and the other as a flag array that is initialized to all ones.
For every position in the flag array that is a 1 it prints the number and every 0 it doesn't print the number. The good news is I figured out issues with all my loops, the issue I am having is saving the value 0 to the flag array at the position it currently is. Everything that I reference talks about using:
sw [register], ([register])
From what I understand that is how you save the contents of one register to the position of the other? It doesn't seem to work for me. I went ahead and posted the code down bellow, It is kind of messy and really long, but my code for recursion is down where it says Eratosthenes.
.data
NUM_ARRAY: .space 800 # 800-byte memory space
FLAG_ARRAY: .space 800 # 800-byte memory space
START_MSG: .asciiz "The prime numbers up to 110 are:\n"
END_MSG: .asciiz "Completed ...."
SPACE: .asciiz " "
NEWLINE: .asciiz "\n"
BUG1: .asciiz "Out of loop"
INK: .asciiz "incrementK"
INX: .asciiz "incrementX"
.text
.globl main
# THE BEGINNING OF MODULE MAIN #######################
main:
# save the ten registers --------------------------
subu $sp, $sp, 48 # stack frame for 12 registers
sw $ra, ($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
sw $s2, 12($sp)
sw $s4, 16($sp)
sw $s5, 20($sp)
sw $t0, 24($sp)
sw $t1, 28($sp)
sw $t2, 32($sp)
sw $v0, 36($sp)
sw $a0, 40($sp)
# initialize the essential parameters -------------
li $s0, 111 # the largest number (always - 1)
li $s1, 10 # the square-root of $s0 register
li $s2, 2 # the initial value for "k"
li $s4, 0 # the first numbers to consider
li $s5, 1 # '1' - it is a prime number
li $t2, 0 # loop ounter
# show an opening message ---------------------------------
li $v0, 4 # system call #4
la $a0, START_MSG
syscall
# initialize the two arrays -------------------------------
la $t0, NUM_ARRAY # set the address of the 1st array
la $t1, FLAG_ARRAY # set the address of the 2nd array
loop1: sw $s4, ($t0) # load a number
sw $s5, ($t1) # load the initial property (1 - a prime)
addi $t2, $t2, 1 # increase the loop counter by one
beq $t2, $s0, EXIT1 # if all the array elements are set up
addi $s4, $s4, 1 # increase the number by one
addu $t0, $t0, 4 # increase the pointer by four bytes
addu $t1, $t1, 4 # increase the pointer by four bytes
j loop1 # repeat to "loop1"
EXIT1: li $s2, 2
li $s6, 2
jal Eratosthenes # start recursive Eratosthenes
li $v0, 4 # system call #4
la $a0, NEWLINE
syscall
li $v0, 4 # system call #4
la $a0, NEWLINE
syscall
li $t2, 0 # reset the loop counter
la $t0, NUM_ARRAY # reset the address of the 1st array
la $t1, FLAG_ARRAY # reset the address of the 2nd array
loop3: lw $a0, ($t1) # load the number there
beq $a0, $zero, SKIP1 # if the target is '0': skip
beq $t2, $zero, SKIP1 # if repeated enough: skip
li $v0, 1 # system call #1
lw $a0, ($t0) # load the number there
syscall
li $v0, 4 # system call #4
la $a0, NEWLINE
syscall
SKIP1: addi $t2, $t2, 1 # increase the loop counter
addu $t0, $t0, 4 # increase the pointer by four bytes
addu $t1, $t1, 4 # increase the pointer by four bytes
blt $t2, $s0, loop3
li $v0, 4 # system call #4
la $a0, END_MSG
syscall
# restore registers ---------------------------------------
lw $ra, ($sp)
lw $s0, 4($sp)
lw $s1, 8($sp)
lw $s2, 12($sp)
lw $s4, 16($sp)
lw $s5, 20($sp)
lw $t0, 24($sp)
lw $t1, 28($sp)
lw $t2, 32($sp)
lw $v0, 36($sp)
lw $a0, 40($sp)
addu $sp, $sp, 48 # delete the stack frame
jr $31 # park it at the parking spot
# THE END OF MODULE MAIN ##########################################
Eratosthenes:
subu $sp,$sp,36
sw $ra, 0($sp)
sw $t5, 4($sp)
sw $t6, 8($sp)
sw $t0, 12($sp)
sw $t1, 16($sp)
sw $t2, 20($sp)
sw $s4, 24($sp)
sw $s5, 28($sp)
sw $s0, 32($sp)
li $s5, 0 #change s5 to 0
li $s6, 2 #reset the x
li $t2, 0
la $t0, NUM_ARRAY #reset Array 1
la $t1, FLAG_ARRAY #reset Array 2
R_Loop:
mult $s2,$s6
mflo $t7
addi $t2,$t2,1
lw $s4, ($t0)
beq $t7, $s4, SKIPone
beq $t2, $s0, EXITL #branch if counter is max
addu $t0, $t0, 4 #next spot in NUM_ARRAY
addu $t1, $t1, 4 #next spot in FLAG_ARRAY
li $v0,1
move $a0, $t7
syscall
li $v0,4
la $a0, NEWLINE
syscall
li $v0,4
la $a0, NEWLINE
syscall
j R_Loop
SKIPone:
addi $s6,$s6,1 #increment x by one
sw $zero, ($t1) #attempt at making position at array 0
#have also tried
#sw $s5, ($t1) #where s5 is initialized at 0
#please take note that offset is 0, because it needs to be
#at the current position at the array
li $v0,4
la $a0, NEWLINE
syscall
li $v0,4
la $a0, NEWLINE
syscall
li $v0,1
move $a0, $t4 #debug aid
syscall
li $v0,4
la $a0, NEWLINE
syscall
li $v0,4
la $a0, NEWLINE
syscall
beq $t2 $s0, EXITL
li $v0, 4
la $a0, INX #debug aid
syscall
j R_Loop
EXITL:
li $t8,10
li $v0, 4
la $a0, INK #debug aid
syscall
beq $s2,$t8, EXITR
addi $s2,$s2,1 #increment k by one
jal Eratosthenes
li $v0 4
la $a0, BUG1
syscall
EXITR:
lw $ra, 0($sp)
lw $t5, 4($sp)
lw $t6, 8($sp)
lw $t0, 12($sp)
lw $t1, 16($sp)
lw $t2, 20($sp)
lw $s4, 24($sp)
lw $s5, 28($sp)
lw $s0, 32($sp)
addu $sp,$sp,36
jr $ra
Any help is appreciated, nothing else seems to work and my teacher is of no help.

Related

MIPS array assign infinity loop

I am trying to fix this problem for hours!!!!!
When I enter 8 integers for the array and then enter 0 to finish reading, when the loop section starts it goes to infinity loop!!
I can't find where's the problem, when I remove the addiu from the $s2 array it works fine but doesn't store the $t1 on the array!
Please HELP!!
.data
array: .space 32
percentage_Array: .space 32
newLine: .asciiz "\n"
.text
main:
la $s1, array
la $s2, percentage_Array
read_numbers:
li $v0, 5
syscall
sw $v0, 0($s1)
addiu $s1, $s1, 4
beqz $v0, continue
j read_numbers
continue:
la $s1, array
loop:
lw $t0, 0($s1)
addiu $s1, $s1, 4
beqz $t0, exit
move $a1, $t0
jal calculate_Ones_and_Bits
move $s6, $v0
move $s7, $v1
#put the total number of ones
add $s0, $s0, $s7
#calculate the percentage
addi $t5, $zero, 100
mult $s7, $t5
mflo $t1
div $t1, $s6
mflo $t1
#-----I THINK HERE IS MY PROBLEM------
#Put the percentages on percentage_Array array
sw $a1, 0($s2)
addiu $s2, $s2, 4
#Check which percentages are greater than 50 and print the numbers
which fulfill the condition
slti $t2, $t1, 50
beq $t2, 1, loop
li $v0, 1
move $a0, $t0
syscall
#lines 66,67,68 are extra just for printing in new line more clearly
li $v0, 4
la $a0, newLine
syscall
j loop
exit:
#lines 73,74,75 are also extra just to print the value of s0, it is
printed here so it
#will be executed after the loop has finished
li $v0, 1
move $a0, $s0
syscall
#tell the OS to exit/finish
li $v0, 10
syscall

Copying an array for sorting not working correctly in MIPS program?

I'm working on a sorting program that sorts an array of integers, for which I copy the array entered in by the user into a new array to be mutated. However, I'm not sure if I'm doing it correctly.
.globl main
.data
input: .asciiz "Enter the size of the array: \n"
entries: .asciiz "Enter the elements of the array, one line at a time: \n"
output: .asciiz "Original array and then sorted array: \n"
space: .asciiz " "
.text
main:
subi $sp, $sp 32
sw $ra, 0($sp)
sw $t0, 4($sp) # the size of the array
sw $t4, 8($sp) # the number 4
sw $t1, 12($sp) # temporary
sw $t2, 16($sp) # array original
sw $t3, 20($sp) # specific element
sw $s1, 24($sp) # copied array
sw $t5, 28($sp) # number to copy
la $a0, input
li $v0, 4
syscall
# get the size
li $v0, 5
syscall
move $t0, $v0
# allocate space for the array on the heap
li $t4, 4
mul $t1, $t0, $t4
li $v0, 9
move $a0, $t1
syscall
move $t2, $v0
li $s0, 0
la $a0, entries
li $v0, 4
syscall
read_array:
# read element
li $v0, 5
syscall
move $t3, $v0
# place in right address
mul $t1, $s0, $t4
add $t1, $t2, $t1
sw $t3, 0($t2)
addi $s0, $s0, 1
blt $s0, $t0, read_array
li $s0, 0
gnome_sort:
# allocate space on heap for copy
mul $t1, $t0, $t4
li $v0, 9
move $a0, $t1
syscall
move $s1, $v0
mul $s2, $t4, $t0
add $s3, $s1, $s2
copy_array:
lw $t5, 0($t2)
sw $t5, 0($s1)
add $t2, $t2, $t4
add $s1, $s1, $t4
blt $s1, $s3, copy_array
li $s0, 0
while_loop:
bgt $s0, $t0, finish_sort
beq $s0, $zero, increase_i
sw $s4, 0($s1)
sw $s5, -4($s1)
bge $s4, $s5, increase_i
j swap_elements
increase_i:
addi $s0, $s0, 1
j while_loop
swap_elements:
la $a0, input
li $v0, 4
syscall
sw $t6, 0($s1)
sw $t7, -4($s1)
lw $t7, 0($s1)
lw $t6, -4($s1)
subi $s0, $s0, 1
j while_loop
finish_sort:
li $s0, 0
la $a0, output
li $v0, 4
syscall
j print_original
print_original:
bge $s0, $t0, print_sorted
lw $s6, 0($t2)
li $v0, 1
move $a0, $s6
syscall
la $a0, space
li $v0, 4
syscall
addi $s0, $s0, 1
j print_original
print_sorted:
li $s0, 0
loop:
bge $s0, $t0, finish
lw $s6, 0($s1)
li $v0, 1
move $a0, $s6
syscall
la $a0, space
li $v0, 4
syscall
addi $s0, $s0, 1
j loop
finish:
li $v0, 10
syscall
After testing this in QTSpim, it seems that you're going out of allocated memory on the line sw $s4, 0($s1)
in the while_loop. This is because $s1 at that point is past the end of the second array you allocated. If you want to use that memory, you will have to syscall for it.
The way you copy the array using lw and sw is correct.

Copy array elements to another array in MIPS assembly

i have to make a program that fills an array with 30 integers entered from keyboard.Then the user type 'c' to copy the array to an other array.i've done with the first step but i cant manage to copy the array to another.
Here is my code
.data
msg1: .asciiz "> "
msg2: .asciiz "type 'c' to copy \n>"
.align 2
array: .space 400
.text
main:
la $t3 array
loop:
la $a0, msg1 #output message 1
li $v0, 4
syscall
li $v0, 5 #read integer input
syscall
move $t0, $v0
beq $t0, -99, endloop #loop until user types -99
beq $t1,30,endloop #get user input up to 30 times
addi $t1, $t1, 1 #counter
sw $t0,($t3)
addi $t3,$t3,4
b loop #loop until it reaches 30
endloop:
la $a0, msg2 #output message 2
li $v0, 4
syscall
li $v0, 12 #read character input
syscall
beq $v0, 'c', COPY
j NEXT
COPY:
NEXT:
The most primitive way to do it is to
la $t1, dst_array
la $t3, src_array
addu $t0, $t3, 30*4 # setup a 'ceiling'
copy_loop:
lw $at, 0($t3)
sw $at, 0($t1)
addu $t1, $t1, 4
addu $t3, $t3, 4
blt $t1, $t0, copy_loop # if load pointer < src_array + 30*4
However, some implementations of MIPS don't use forwarding, and therefore you have to wait until $at is written back. For that purpose, there may be either a stall (which you could get rid off)
subu $t1, $t1, 4
copy_loop:
lw $at, 0($t3)
addu $t1, $t1, 4
addu $t3, $t3, 4
sw $at, 0($t1)
or a load delay slot, which usually takes 1 cycle, making it
copy_loop:
lw $at, 0($t3)
addu $t1, $t1, 4
sw $at, 0($t1)
addu $t3, $t3, 4
Generally speaking, it depends :)

MIPS Searching an array, with stack implemented

So this comes from Exercise 6.2 of the book MIPS Assembly Language Programming, by Britton. I need to use a byte size array with 10 preset integers, prompt the system to ask the user to enter a number to search for. If the number is found, print the element at which it is stored, if not found print a different message. I need to do this using the stack, which is were I believe I am getting my error. I am almost positive its in the stack, but I have tried everything that I can think of. Any suggestions would be extremely appreciated. Thanks! Here is my code so far:
Solved: Code has been updated.
X: .byte 1, 27, 92, 46, 72, 8, 13, 93, 65, 112
N: .word 10
srch: .asciiz "Please enter a number to search for: "
posi: .asciiz "That numbers location is in element "
fals: .asciiz "That number is not in the array."
nxln: .asciiz "\n"
.text
main: la $s0, X
la $s1, N
la $a0, srch
li $v0, 4
syscall
li $v0, 5
syscall
move $t2, $v0
addiu $sp, $sp, -24 # stack prep
sw $s0, 0($sp)
sb $s1, 4($sp)
sb $t2, 8($sp)
jal search
lb $t2, 12($sp)
lb $t3, 16($sp)
addiu $sp, $sp, 24
la $a0, posi
li $v0, 4
syscall
li $v0, 1
move $a0, $t2
syscall
li $v0, 10
syscall
search:
lw $t5, 0($sp) # get &X
lb $t8, 4($sp) # get N
lb $t7, 8($sp) # get V
move $t6, $t8
addi $t6, $t6, -1 # $t6 = N - 1
loop:
lb $t4, 0($t5) # get a character (always get my error here)
addi $t5, $t5, 1 # increment pointer
beq $t4, $t7, found
addi $t6, $t6, -1 # decrement loop counter
bgez $t6, loop
li $t4, -1
sw $t4, 16($sp)
b exit
found:
sub $t6, $t6, $t8
sb $t6, 12($sp)
jr $ra
exit:
la $a0, fals
li $v0, 4
syscall
li $v0, 10
syscall

printing of integers mips

I try to add numbers to a array and then I try to print those numbers, but when I add mine numbers and I try to print and then I got different numbers. How is that possible?
My code is:
#----------------------------------- Array Vullen -----------------------------------------------------
.data
question1_msg: .asciiz "How much integer do you want to give?\n"
question2_msg: .asciiz "give a number?\n"
.text
question_numbers:
la $a0, question1_msg #load the question in $a0
li $v0, 4
syscall
answer_numbers:
li $v0, 5 #read the answer of previous question
syscall
move $t0, $v0
move $t9, $t0
move $t8, $t0
generate_array:
sll $t0, $t0, 2 #create array
move $a0, $t0
li $v0, 9
syscall
move $t3, $v0 #put the stack pointer in a temperay register
move $t4, $v0
add_numbers_array:
bge $t1, $t9, Call_procedure # if $t1 >= $t0 then exit
#ask questions
la $a0, question2_msg #load the question in $a0
li $v0, 4
syscall
#read numbers
li $v0, 5
syscall
move $t2, $a0
#add number en go to the next array point
sw $t2, ($t3)
add $t3, $t3, 4
add $t1, $t1, 1
#get back to the begin of the loop
b add_numbers_array
#-------------------------------------Array Printen------------------------------------------------
Call_procedure:
li $t1, 0
la $a1, ($t8) # load the couple of numbers
la $a2, ($t4) # load the starting adress of the array
jal Print
b exit
Print:
bge $t1, $a1, return # if $t1 >= $t0 then exit
lw $t2, ($a2) #load integer and print
move $a0, $t2
li $v0, 1 # print the number in the array
syscall
addu $a2, $a2, 4 #increase the sp
addi $t1, $t1, 1 #increase the number printed
b Print
return:
jr $ra
exit:
li $v0 , 10 # let the code end
syscall
I see 2 errors:
1.
#read numbers
li $v0, 5
syscall
move $t2, $v0
This should be $v0, not $a0
2.
move $a1, $t8
move $a2, $t4
instead of
la $a1, ($t8) # load the couple of numbers
la $a2, ($t4) # load the starting adress of the array

Resources