MIPS Searching an array, with stack implemented - arrays

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

Related

Trying to change array value in MIPS assembly

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.

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

MIPS Values arent able to be accessed from memory

So the issue is that whenever i try to access the integers placed into the array which seems to work perfectly and theyre even saved to an address of +0 and +4 respectively and so on for the amount of values there are but when i attempt to take them out to use them for sorting purposes they're seemingly not being loaded into the $t4 and $t5 values. below is my code im using for this, why wont the values transfer when loading them from 0,4($s1) where they are placed?
.data
prompt1: .asciiz "Enter the array size \n"
prompt2: .asciiz "Enter integers to fill the array \n"
prompt3: .asciiz "Sorted Array: "
.text
main:
li $t0, 0
la $a0, prompt1
li $v0, 4
syscall
li $v0, 5
syscall
move $t0, $v0 #array size
add $t9, $t0, $t0
li $v0, 9
la $a0, ($t0)
syscall
move $s0, $v0 #array address w/ size in memory
add $s1, $zero, $s0
loop:
la $a0, prompt2
li $v0, 4
syscall
li $v0, 5
syscall
beqz $t0, sort
sw $v0, 0($s1)
addiu $s1, $s1, 4
subiu $t0, $t0, 1
bnez $t0, loop
sort:
lw $t4, 0($s1)
lw $t5, 4($s1)
blt $t5, $t4, swap
addiu $s1, $s1, 4
subiu $t9, $t9, 1
bnez $t9, sort
j exit
swap:
sw $t4, 4($s1)
sw $t5, 0($s1)
exit:

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 - Error when printing data into array

So im attempting to put numbers 1-200 in an array. The array is at the bottom of the code. I keep getting errors when i try to print this, can anyone spot the error with me putting in the numbers? The numbers in the array are supposed to go from 1-200, so $t3 increments each time. Any advice would be greatly appreciated.
main:
.text
lw $t0, numbers_size # loads the size of the array into the loop
la $t1, numbers # $t1 gets the number array
li $t2, 0 # loop control variable
li $t3, 1 # value stored inside numbers
li $v0, 4
la $a0, test_2 # print before loop
syscall
number_for:
bge $t2, $t0, end_for
sw $t3, ($t1)
add $t1, $t1, 4
add $t2, $t2, 1
add $t3, $t3, 1
j number_for
end_for:
lw $t0, numbers_size # loads the size of the array into the loop
la $t1, numbers # $t1 gets the number array
li $t2, 0 # loop control variable
j print_numbers
.data
test: .asciiz "Printing numbers:"
test_2: .asciiz "Before loop:"
numbers:
.word 0:200
numbers_size:
.word 200
This may help you:
.text
main:
lw $t0, numbers_size # loads the size of the array into the loop
la $t1, numbers # $t1 gets the number array
li $t2, 0 # loop control variable
li $t3, 1 # value stored inside numbers
li $v0, 4
la $a0, test_2 # print before loop
syscall
j number_for
li $v0, 10
syscall
number_for:
bge $t2, $t0 end_for
sw $t3, ($t1)
addi $t1, $t1, 4
addi $t2, $t2, 1
addi $t3, $t3, 1
b number_for
end_for:
lw $t0, numbers_size # loads the size of the array into the loop
li $t1, 0
li $t2, 0 # loop control variable
buc:
bge $t2, $t0 end
lw $a0, numbers($t1) # Printing integer from array
li $v0,1
syscall
la $a0, space #load a space: " "
li $v0, 4 #print string
syscall
addi $t1, $t1, 4
addi $t2, $t2, 1
b buc
end:
jr $ra
.data
test: .asciiz "Printing numbers:"
test_2: .asciiz "Before loop:\n"
space: .asciiz " "
numbers_size:
.word 200
numbers:
.word 0:200

Resources