how to find min and max in an array MIPS - mips

i can find the max perfectly fine but when it comes to finding the min, im having some trouble, my max finds the max number good but my min always prints out 0 no matter what, i cant seem to find out what is wrong with my code, does anyone see the flaw in my code?
For exmaple:
i enter in 5 integers
5 10 15 20 25
Array: 5,10,15,20,25
Min: 0
Max: 25
.text
.globl main
main:
la $a0, ask #ask user for integer thats going to be the size of the array
li $v0, 4
syscall
li $v0, 5 #store that int
syscall
move $t1,$v0 #size of my array stored in $t1
la $t0, array #load address of our array
li $t2, 0 #counter = 0
lw $t3,($t0) #initialize min = array[0]
lw $t4,($t0) #initialize max = array[0]
while:
la $a0, intask #ask user for integer
li $v0, 4
syscall
li $v0, 5 #store that int
syscall
sw $v0, ($t0) #store that int in the array
end: add $t0, $t0, 4 #increment the array to the next index
add $t2, $t2, 1 #increment the counter by 1
blt $t2, $t1,while #branch to while if counter < size of array
endw:
la $a0,display # Display "Array is: "
li $v0,4
syscall
li $t0, 0 # initilize array index value back to 0
li $t2, 0 # initial size counter back to zero
la $t0, array # load address of array back into $t0
sprint:
lw $t6,($t0) #load word into temp $t2
move $a0, $t6 #store it to a safer place
li $v0, 1 #print it out
syscall
la $a0,space # Display " "
li $v0,4
syscall
add $t0, $t0, 4 #increment the array to the next index
add $t2, $t2, 1 #increment the counter by 1
blt $t2, $t1,sprint #branch to while if counter < size of array
li $t2, 0 # initial size counter back to zero
la $t0, array # load address of array back into $t0
add $t0, $t0, 4 #increment the array to the next index
add $t2, $t2, 1 #increment the counter by 1
loop: lw $t8,($t0) # t8 = next element in array
bge $t8, $t3, notMin #if array element is >= min goto notMin
move $t3,$t8 #min = array[i]
j notMax
notMin: ble $t8,$t4, notMax #if array element is <= max goto notMax
move $t4,$t8 #max = array[i]
notMax: add $t2,$t2,1 #incr counter
add $t0,$t0, 4 #go up in index
blt $t2, $t1,loop #if counter < size, go to loop
eprint:
la $a0,nextline # Display "\n"
li $v0,4
syscall
la $a0,min # Display "min number is "
li $v0,4
syscall
move $a0, $t3 #displays min number in array
li $v0,1
syscall
la $a0,nextline # Display "\n"
li $v0,4
syscall
la $a0,max # Display "max number is "
li $v0,4
syscall
move $a0, $t4 #displays max number in array
li $v0,1
syscall
li $v0,10 # End Of Program
syscall
.data
array: .space 100
ask: .asciiz "How many numbers will be entered? no more than 15 numbers!: "
intask: .asciiz "Enter an Integer: "
min: .asciiz "The minimum number is: "
max: .asciiz "The maximum number is: "
display: .asciiz "Array: "
space: .asciiz " "
nextline: .asciiz "\n"

You are initializing $t3 (which is used for storing min) to array[0] before any values are stored in array, so $t3 ends up being initialized to 0.
It should be fine if you initialize $t3 to array[0] after values have been entered into array.

Related

Why is my MIPS assignment not printing what it should>

I'm sure I've done the math correct for both factoring and amicability, but it doesn't print past the range and I don't know why. Is my math incorrect? Or am I not actually printing the amicability out?
#all the string variables
.data
startrange: .asciiz "Input the start of the range: " #where the range begins
endrange: .asciiz "What is the end of the range: " #where the range ends
pairs: .asciiz "The pairs of amicable numbers are: " #results of amicable #s in range
quit: .asciiz "Unable to check non-positive values\nExiting..." #circumstance for a < 0 or b < 0
swap: .asciiz "End of range < start of range -- swapping values" #if the end of range is less than the start of range, swap the values
range: .asciiz "\nRange of numbers: " #what the range is (startrange -> endrange)
line: .asciiz "-" #dash for range
output1: .asciiz " are amicable numbers" #results if amicable
output2: .asciiz " are not amicable numbers." #results if not amicable
a: .word 0 #input of startrange
be: .word 0 #input of endrange
.text
main:
la $a0, startrange #load address startrange into $a0
li $v0, 4 #gets ready to print string
syscall #prints out startrange
la $s0, a #loads address of startrange input, a, into $s0
li $v0, 5 #gets ready to read string
syscall #reads startrange input, a
addi $s0, $v0, 0
jal negativeInput #calls for negativeInput fxn to check for negative inputs in a or be
la $a0, endrange #load address endrange into $a1
li $v0, 4 #gets ready to print string
syscall #prints out endrange
la $s1, be #loads address of endrange, be, input into $s1
li $v0, 5 #gets ready to read string
syscall #reads endrange input, be
addi $s1, $v0, 0
#if(a < 0 || b < 0) then exit
jal negativeInput #calls for negativeInput fxn to check for negative inputs in a or be
#if(b < a) swap values
jal swapping #jumps to swapping fxn
#print out range of numbers between a and b
jal printRange #jumps to printrange method
jal isFactor #calls for isFactor fxn to check is inputs have factors
jal isAmicable #calls for isAmicable fxn to check is inputs are amicable
negativeInput:
slt $t1, $s0, $zero #if $s0 (a or be) < 0 put in $t1
bne $t1, $zero, negativeTrue #if above is true (a !> 0) jumps to negativeTrue fxn
jr $ra #return to main
negativeTrue:
la $a0, quit #load string quit into $a0
li $v0, 4 #specifies the print string service
syscall #prints out
j exit
swapping:
slt $t1, $s1, $s0 #if $s1 (be) is < $s0 (a) put in $t1
bne $t1, $zero, swapTrue #if above is true (a > b) jumps to swaptrue fxn
jr $ra #returns to main
swapTrue:
la $a0, swap #load string swap into $a0
li $v0, 4 #gets ready to print
syscall #prints out
move $t2, $s0 #moves input a into $t2
move $s0, $s1 #moves input be into $s0
move $s1, $t2 #moves input a into $s1
#addi $t4, $s0, 0 #gets ready to start loop at beginning (a)
printRange:
la $a0, range #loads range statement into $a0
li $v0, 4 #gets ready to print
syscall #prints out
li $v0, 1 #ready to print int
move $a0, $s0 #moving input a into $a0
syscall #printing it out
la $a0, line #moves line statement (-) into $a0
li $v0, 4 #ready to print string
syscall #prints out
li $v0, 1 #ready to print int
move $a0, $s1 #moves input be into $a0
syscall #prints out
exit:
li $v0, 10
syscall
isFactor:
addi $t6, $s0, 0 #i = a to start loop
addi $t4, $zero, 0 #sum_a = 0
blt $t6, $s0, isFactorLoop #while i < a jump to isFactorLoop fxn
isFactor2:
addi $t6, $s1, 0 #i = be to start loop
addi $t4, $zero, 0 #sum_be = 0
blt $t6, $s1, isFactorLoop2 #while i < b jump to isFactorLoop2 fxn
isFactorLoop:
div $s0, $t6 #a/i
mfhi $t5 #a/i == $t5
beq $t5, 0, isFactorLoopTrue #if a/i == 0 jump to isFactorLoopTrue fxn
isFactorLoop2:
div $s1, $t6 #be/i
mfhi $t5 #be/i == $t5
beq $t5, 0, isFactorLoopTrue2 #if be/i == 0 jump to isFactorLoopTrue fxn
isFactorLoopTrue:
add $t4, $t6, $t4 #sum_a += i
move $s3, $t4 #moves sum_a into saved register
j isFactorLoop #repeats loop
isFactorLoopTrue2:
add $t4, $t6, $4 #sum_be += i
move $s4, $t4 #moves sum_be into saved register
j isFactorLoop2 #repeats loop
isAmicable:
addi $t7, $s0, 0 #a/startrange
addi $t8, $s1, 0 #be/endrange
addi $t6, $zero, 0 #i=0
blt $t6, $t8, isAmicableLoop #if i < be jump
beq $t6, $t8, isAmicableLoop #if i == be jump
isAmicableLoop:
addi $t9, $s1, 0 #j = be
bgt $t9, $t7, isAmicableIf #if j > a jump
beq $t9, $t7, isAmicableIf #if j == a jump
isAmicableIf:
#if sum_a == be && sum_be == a they're amicable
beq $s3, $s1, printIsAmicable #if sum_a == be jump
beq $s4, $s0, printIsAmicable #if sum_b == a jump
bne $s3, $s1, printIsNotAmicable #if sum_a != be jump
bne $s4, $s0, printIsNotAmicable #if sum_be != a jump
printIsAmicable:
la $a0, output1 #load address startrange into $a0
li $v0, 4 #gets ready to print string
syscall
printIsNotAmicable:
la $a0, output2 #load address startrange into $a0
li $v0, 4 #gets ready to print string
syscall
I'm sure I did a system call to at least print out the string but thats not working. Even jumped back to main and didn't work. All it prints out to is the range, and doesn't say whether the numbers within that range are amicable.
The problem lies in this function:
printRange:
la $a0, range #loads range statement into $a0
li $v0, 4 #gets ready to print
syscall #prints out
li $v0, 1 #ready to print int
move $a0, $s0 #moving input a into $a0
syscall #printing it out
la $a0, line #moves line statement (-) into $a0
li $v0, 4 #ready to print string
syscall #prints out
li $v0, 1 #ready to print int
move $a0, $s1 #moves input be into $a0
syscall #prints out
exit:
li $v0, 10
syscall
It's important to remember that a label does not alter execution flow simply by existing. The program is printing the range and then "falling through" to your exit routine. This is because labels are merely a hardware abstraction, a convenience so that you don't have to adjust your "line numbers" (read: memory offsets) of your jal, b, and j statements every time you change your code. The assembler converts your source code, which specifies a label, to either a jump to the memory address where the instruction directly beneath that label is stored, or the distance between the current program counter value and that instruction (measured in bytes), as appropriate. The labels no longer exist in your assembled executable program.
Not only that, your isFactorLoop appears to have no way to exit and thus would loop forever.

MIPS Print multiples of 2 and 3 in the range 0 to n

I have just started MIPS and I am trying to print all numbers that are multiples of 2 and 3 between a range of 0 to n. I have coded a program that can print the numbers from 0 to n already.
I know that I should try use the "and $t0, $v0, 2" and the "and $t0, $v0, 3" to check if it is a multiple but I get mixed up in the MIPS code as it is very confusing for a beginner. Help would be greatly appreciated!
main:
la $a0, prompt
li $v0, 4
syscall
li $v0, 5
syscall
li $t0, 1
move $t2,$v0;
loop:
bgt $t0, $t2 end
move $a0, $t0
li $v0, 1
syscall
li $a0, '\n'
li $v0, 11
syscall
add $t0, $t0 1
b loop
end:
jr $ra
.data
prompt:
.asciiz "Enter a number: "
This is one approach for this problem
#for (int i =0;i<=n; i++)
#if (i%2 ==0) && (i%3==0)
#print i;
.data
prompt: .asciiz "enter value for n: "
newline: .asciiz "\n"
.text
.globl main
main:
li $t5 0 #initialising i = 0
#for printing prompt
li $v0 4
la $a0 prompt
syscall
#user input reading
li $v0 5
syscall
move $t1 $v0
#displaying on console
move $a0 $t0
li $v0 1
syscall
move $v0 $t0
loop:
beq $t5 $t1 end #checking if i=n
#checking multiples of 2
div $t2 $t5 2
mfhi $t2 #remainder
beq $t2 0 equal #if remainder 0, jump to equal
addi $t5 $t5 1 #increment i by 1
j loop
equal:
#beq $t2 $t3 answer
#checking multiples of 3
div $t3 $t5 3
mfhi $t3 #remainder
beq $t3 0 equal2 #if remainder 0, jump to equal2
addi $t5 $t5 1 #if remainder != 0, incrementing i and jumping to loop
j loop
equal2:
beq $t2 $t3 answer #if both remainder equal to zero, jump to answer
answer:
move $a0 $t5 #moving the value of i for which i is a multiple of 2 and 3
li $v0 1 #printing the answer
syscall
#giving space of a line
li $v0,4
la $a0, newline
syscall
addi $t5 $t5 1 #incrementing i
j loop
#terminating
end:
li $v0, 10
syscall

MIPS program to find the positive sum and negative sum of an array

Here is the code to find the sum of positive number and negative number. However, the code have arithmetic overflow when running (runtime exception at 0x00400034). The basic idea is to use the for loop but the error occured. Did I miss any element for doing the for loop?
.data
array: .word -13, 82, 56, 63, -54
length: .word 10
newLine: .ascii "\n"
posSumMsg: .ascii "Positive value = "
negSumMsg: .ascii "Negative value = "
posSum: .word 0
negSum: .word 0
.text
.globl main
main:
la $t0, array #the starting address of the array
li $t1, 0 # set the loop index, where i = 0
lw $t2, length # length
li $t3, 0 # initialize the sum to be 0 for pos_sum
li $t5, 0 # initialize for neg_sum
#start of loop
sumLoop:
lw $t4, ($t0) #get the array[i]
blt $t4, 0, getNegSum #jump to the negative sum calculation block for negative number
bgt $t4,0, getPosSum #jump to positive sum calculation block for positive number
#calcuates the sum for positive numbers
getPosSum:
add $t3, $t3, $t4 #sum = sum + array[i]
j loopback
getNegSum:
add $t5, $t5, $t4
#loopback of the array
loopback:
add $t1, $t1, 1 #i = i+1
add $t0, $t0, 4 # update the address of the array
bnez $t4, sumLoop # stop the for loop if the last elemnt is a 0, otherwise loop back
#store the sum
sw $t3, posSum
sw $t5, negSum
#print a message
li $v0, 4
la $a0, posSumMsg
syscall
#print value
li $v0, 1
move $a0, $t3
syscall
#print a message
li $v0, 4
la $a0, negSumMsg
syscall
#print a value
li $v0, 1
move $a0, $t5
syscall
#Terminate the program
li $v0, 10
syscall
.end main

MIPS - Printing a certain number of characters from a string

If given a number, I want to print out the first 'x' number of letters from the alphabet. I've setup a counter to determine the number of iterations the loop goes through, but I do not know how to extract the correct number of letters from the alphabet string.
Here's what I've done so far:
.data
alphabet:
.space 28
msg1: .ascii " Please enter an integer from 1-26:"
msg2: .ascii "abcdefghijklmnopqrstuvwxyz"
.text
.globl main
main:
li $v0, 5 # syscall for read_int
syscall
add $a0, $v0, $zero
li $t0, 0
li $t1, 26 # loop will start from zero and iterate to 26
loop:
la $t2, 0($a0)
beq $t0, $t2, end # once $t1 and $a0 are equal, loops stops
#li $t2, 1
#blt $t1, $t2, nomodify # do nothing if int less than 0
#li $t2, 26
#bgt $t0, $t2, nomodify # do nothing if int greater than 25
addi $t0, $t0, 1 # add 1 to $t1
j loop # jump back to top
end:
# Here is where I want to take 'x' number of iterations and convert it to
# the string of 'x' letters
li $v0, 10
syscall
Any help would be appreciated.
Having all the characters in a string is unnecessary for this task. Characters are integers, so you can just start at 'a' and count upwards:
# Assuming the loop count is in $t0
li $a0, 'a' # start at character 'a'
print_chars:
li $v0, 11
syscall # syscall 11 = print_character
addiu $a0, $a0, 1 # set $a0 to the next character
addiu $t0, $t0, -1
bne $t0, $zero, print_chars

Setting input value to Array - MIPS

the program is about done, I am just having an issue with getting the value of $v0 to be put into the array "intarray" each time it loops through, e.g input "1" at intarray[0], "2" at intarray[1] etc...
The program asks for 5 integers via a loop. I need to set the integers into the intarray at each of the 5 spots. I don't understand how to do this in MIPS.
I am also trying to get the final value of $t1 into the variable "total", but I think that requires the same thing as intarray. The printing of these arrays would be good to know too.
The main issue is how to take a value in for example $t0 and put it into a position such as intarray[1].
Thanks for your help.
Here is the code:
.data
intarray: .word -1, -1, -1, -1, -1
total: .word 0
result: .asciiz "Enter a series of 5 integers, one per line: "
thetot: .asciiz "Your total is: "
.text
main:
li $v0, 4 #call to print string
la $a0, result #print string from location
syscall
li $t0, 0 #set $t0 = i = 0
li $t1, 0 #set $t1 = tot = 0
la $t2, intarray #puts the address of intarray into $t2
loop:
li $v0, 5 #system call code to accept integer
syscall
add $t1, $t1, $v0 #moves integer to $t0
add $t0, $t0, 1
blt $t0, 5, loop #end loop if i<5
li $v0, 4
la $a0, thetot
syscall
li $v0, 1
la $a0, ($t1)
syscall
li $v0, 10 #exits program
syscall