Function to find the MAX and its position on an array - arrays

I have to find the max element and its position on an array(the position starts with 1)( if the array doesn't contain any elements I have to return position=0 and max=smallest negative number). I think that my code is ok (apart from setting the max to the lowest number possible, that I have doubt about) but I have no idea what I need to start my code with, like save the last thing stored in the registers. Also I can't compile it (probably because of the pseudo-instructions).
I have tried writing my program in c and then compiling to MIPS but it still wouldn't work.
MaxAndArg:
li $v0, -2,147,483,648 # $v0(MAX) is the smallest negative number
li $v1, 0 # $v1(POSITION) starts from zero
li $t3, 0 # $t3(i in a normal language) will be used to loop
li $t4, 0 # $t4 will be used to show the position in the array
L2:
beq $t3, $a1, EXIT # if (i = array size) goto EXIT
sll $t4, $t4, 2 # $t4 = $t4 * 4
add $a0, $t4, $a0 # $a0 = $a0 + $t4 (next element in the array)
blt $v0, a0, L1 # if (max < a[j]) goto L1
addi $t3, $t3, 1 # i++
addi $t4, $t4, 1 # array_position++
j L2
L1:
addi $v0, $a0, 0 # $v0 = $a0
addi $v1, $t3, 1 # $v1 = i + 1 (probably works)
addi $t3, $t3, 1 # i++
addi $t4, $t4, 1 # array_position++
j L2
EXIT:
jr $ra #return

Related

I need 10 integer of array and display the sum and here is my code I dont know where the error is

Write a MIPS program that defines a one-dimensional array of 10 integers in the static area of the data segment, asks the user to input all 10 array elements, computes, and displays their sum.
.data
arr: .word 1,2,3,4,5,6,7,8,9,10
msg: .asciiz "Result: "
.text
.globl main
main:
addi $t0, $zero, 0 # clear i
addi $t1, $zero, 0 # clear sum
ori $t2, $zero, 10 # Initializing t2 to its constant value 10
la $t3, arr # load address of array into t4
loop:
slt $t4, $t0, $t2 # compare, $t4 = i < sum ? 1 : 0
beq $t4, $zero, end # if i is not < 10, exit the loop
lw $t4, 0($t3) # load current array element into t4
add $t1, $t1, $t4 # add it to sum
add $t0, $t0, 1 # increment i
add $t3, $t3, 4 # increment current array element pointer
j loop
end:
addi $v0, $zero, 4 # Now we print out result: string
la $a0, msg
syscall
addi $v0, $zero, 1 # followed by the actual sum (which is in t1)
add $a0, $t1, $zero
syscall
jr $ra
.end main

MIPS - Having trouble finding the minimum value in an array

so I've been given an assignment in which I'm supposed to find the index of the max and min values in a user-created 10 digit array in MIPS assembly language. I've been able to find the max value but I'm having trouble finding the min value. I figured it should be a simple solution once I find the max value but I was wrong.
Here is what i have to find the max value:
deleteMax:
# $s7 is the register where the address of the array is stored
# $s0 is the register where the array size is stored
# Clear out unimportant registers
addi $s1, $zero, 0
addi $t0, $zero, 0
addi $s3, $zero, 0
addi $s4, $zero, 0
addi $t6, $zero, 0
addi $t7, $zero, 0
addi $t0, $zero, 0 # Address of first element in bytes
li $t3, -1 # Max index
li $s2, 0 # Max value
li $t1, 0 # Counter
loop:
sll $s1, $t1, 2
add $s1, $s1, $s7
lw $s3, 0($s1) # Load the first element into $s3
li $v0, 1
move $a0, $s3
syscall
slt $t2, $s3, $s2 # If $s3 < $s2, $t2 = 1, if $s3 >= $s2, $t2 = 0
bne $t2, $zero, find_max
ori $s2, $s3, 0 # Updates the maximum value
ori $t3, $t1, 0 # Updates the maximum value index
find_max:
addi $t1, $t1,1 # Increase the counter
bne $t1, $s0, loop # if the counter hasn't reached the end, go
back to the loop
j print_max
This does what I want: Find the max and it's index. However when I try switching these 2 lines of codes:
slt $t2, $s3, $s2 # If $s3 < $s2, $t2 = 1, if $s3 >= $s2, $t2 = 0
bne $t2, $zero, find_max
to lets say:
slt $t2, $s3, $s2 # If $s3 < $s2, $t2 = 1, if $s3 >= $s2, $t2 = 0
bne $t2, 1, find_max
The min value comes out to 0?
I'm not sure why this is happening and unsure what I can do for my current situation to find the min value.
I hope I've explained myself and my code + comments have explained the situation enough. Im more than happy to answer any more confusion you guys may have.

Array sorting in MIPS

So I am working on an assignment to sort an array in MIPS. The data to sort is given in a separate .asm file as follows:
.data
.word 3
.word 40
.word 30
.word 70
.text
I decided to use bubble sort. I am fairly certain that my algorithm is sound, and it appears to sort the data correctly. The fun thing about this project is that the values we sort will be played as MIDI notes as a means of testing the program (so, naturally, the notes should play in ascending order). This is working pretty well when I test my code, however, I'm hearing a few strange beats at the end of the MIDI notes. I stepped through my code and discovered that, at the end, $t1 (the value I use to compare to my loop iterator for completeness) holds a value of 7, when I expected it to hold a value of three. I assign $t1 as 0($t2), $t2 is 0x10010000 which I assume is still the base address of my array. The base address of the array should hold 3, shouldn't it?
I'm a little confused about why $t1 is 7 at all... any advice? I have included all of my code below.
#ec2.asm
.include "ec2_data.asm" #must be in the same directory as ec2.asm
#ec2_data.asm: puts some values in the "data segment"
#the first value is the number of values to sort (n)
#the remaining n word values are the data to sort
#the values will be stored in memory as word values starting
# address 0x10010000
j main
#$t2 is hasChanged
#$t3 is itemCount
#$t4 is i, our iterator in the for loop
#$t5 is array[i] (temp)
#$t6 is array[i+1] (temp)
while_label:
beq $t2, $zero, done_sorting #checks to see if the previous iteration switched any values. If not, we are done.
addi $t2, $zero, 0 #initialize hasChanged to 0
addi $t3, $t3, -1 #decrement itemCount by -1
addi, $t0, $t0, 4 #add 4 to the array offset
addi, $t4, $zero, 0 #set our for loop iterator to 0
for_label:
lw $t5, 0($t0) #set a temp value equal to array[i]
lw $t6, 4($t0) #set a temp value equal to array[i+1]
beq $t4, $t3, while_label #for loop: if i = itemcount, we have incremented all the way through our for loop
bge $t6, $t5, skip_swap #if array[i+1] is greater than or equal to array[i], we don't need to swap these values
#swap
sw $t6, 0($t0) #set array[i] equal to array[i+1]
sw $t5, 4($t0) #set array[i+1] equal to the temp value
addi $t2, $t2, 1 #set hasChanged to 1 to indicate that a swap has been made
skip_swap:
addi, $t4, $t4, 1 #increment i by 1 (for loop iterator)
j for_label #keep the for loop going!
main:
#read values
addi $t0, $zero, 0x10010000 #sets $t0 to be the base address of the array
addi $t2, $zero, 1
lw $t3, 0($t0) #stores n in $t3
j while_label
done_sorting:
# adapted from MIDI example
#duration 25 ms
#instrument (whichever)
#volume 64
addi $v0, $zero, 33 # midi out synchronous
addi $t2, $zero, 0x10010000 # address of original array (which should by now be sorted)
addi $a1, $zero, 250 # duration (ms)
addi $a2, $zero, 1 # instrument
addi $a3, $zero, 64 # volume
addi $t0, $zero, 0 # counter
lw $t1, 0($t2) # end of the loop (should be n)
addi $t1, $t1, 4 # adds four to the array offset in $t1
lw $a0, 0($t2) # stores the first sorted value ( 4($t1) ) in $a0
midi_loop:
beq $t0, $t1, done
addi $t2, $t2, 4
lw $a0, 0($t2)
syscall
addi $t0, $t0, 1
j midi_loop
done:
#addi $v0, $zero, 10 # syscall for exit
#syscall # clean exit
Your sorting algorithm is quite broken. You haven't noticed that because it happens to get the right answer with your test data. It will produce the wrong answer with other test data (e.g. I believe your algorithm will sort 70, 40, 30 to 40, 30, 70).
But your question was about why $t1 ends up with value 7. The answer is simple. You wrote this:
addi $t2, $zero, 0x10010000 # address of original array (which should by now be sorted)
addi $a1, $zero, 250 # duration (ms)
addi $a2, $zero, 1 # instrument
addi $a3, $zero, 64 # volume
addi $t0, $zero, 0 # counter
lw $t1, 0($t2) # end of the loop (should be n)
addi $t1, $t1, 4 # adds four to the array offset in $t1
We can see that you set $t2 to 0 + 0x10010000 = 0x10010000. Then you load the word at 0($t2) (= 0x10010000) into $t1. The word at 0x10010000 is 3, so at that point $t1 is 3. Then you add 4 to $t1, storing the result in $t1. At that point $t1 is 7. You never modify $t1 after that.
SO I really shouldn't have asked this question without giving my code another once-over. The errors were extremely simple. This appears to work.
#ec2.asm
.include "ec2_data.asm" #must be in the same directory as ec2.asm
#ec2_data.asm: puts some values in the "data segment"
#the first value is the number of values to sort (n)
#the remaining n word values are the data to sort
#the values will be stored in memory as word values starting
# address 0x10010000
j main
#$t2 is hasChanged
#$t3 is itemCount
#$t4 is i, our iterator in the for loop
#$t5 is array[i] (temp)
#$t6 is array[i+1] (temp)
while_label:
beq $t2, $zero, done_sorting #checks to see if the previous iteration switched any values. If not, we are done.
addi $t2, $zero, 0 #initialize hasChanged to 0
addi $t3, $t3, -1 #decrement itemCount by -1 WHY
addi, $t0, $zero, 0x10010000 #add 4 to the array offset
addi, $t4, $zero, 0 #set our for loop iterator to 0
for_label:
addi, $t0, $t0, 4
lw $t5, 0($t0) #set a temp value equal to array[i]
lw $t6, 4($t0) #set a temp value equal to array[i+1]
beq $t4, $t3, while_label #for loop: if i = itemcount, we have incremented all the way through our for loop
bge $t6, $t5, skip_swap #if array[i+1] is greater than or equal to array[i], we don't need to swap these values
#swap
sw $t6, 0($t0) #set array[i] equal to array[i+1]
sw $t5, 4($t0) #set array[i+1] equal to the temp value
addi $t2, $t2, 1 #set hasChanged to 1 to indicate that a swap has been made
skip_swap:
addi, $t4, $t4, 1 #increment i by 1 (for loop iterator)
j for_label #keep the for loop going!
main:
#read values
addi $t0, $zero, 0x10010000 #sets $t0 to be the base address of the array
addi $t2, $zero, 1
lw $t3, 0($t0) #stores n in $t3
j while_label
done_sorting:
# adapted from MIDI example
#duration 25 ms
#instrument (whichever)
#volume 64
addi $v0, $zero, 33 # midi out synchronous
addi $t2, $zero, 0x10010000 # address of original array (which should by now be sorted)
addi $a1, $zero, 250 # duration (ms)
addi $a2, $zero, 1 # instrument
addi $a3, $zero, 64 # volume
addi $t0, $zero, 0 # counter
lw $t1, 0($t2) # end of the loop (should be n)
lw $a0, 0($t2) # stores the first sorted value ( 4($t1) ) in $a0
midi_loop:
beq $t0, $t1, done
addi $t2, $t2, 4
lw $a0, 0($t2)
syscall
addi $t0, $t0, 1
j midi_loop
done:

How to print a full array in MIPS, and sum certain integers of an array

I am having an issue with the following code I am using for an assignment.. Note, I do not want anybody just giving me code, I am really trying to understand MIPS. I am using the QTSpim simulator to run my MIPS code.
The following code is supposed to allow the user to enter 10 integers from the keyboard, then take those integers and sum the ones that are less than the first inputted integer (ie. 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 would sum all numbers except 10, to equal 45). Then, the program should output the array in the order it was given. Currently, my code is allowing the user to enter 10 integers, but then funny things happen. It sums the numbers in a way that I cannot follow (the most common sums somehow being 0, 4, and 50), and will then only print out 4 integers for the array list (which seems to be as follows: firstNumber, secondNumber, lastNumber, 10) I am really confused as to why this happens. Also, for some instances of integers, it will create an infinite loop outputting 0.
I've been at this for hours, can somebody please give me some advice or pointers?
All help is appreciated. Thanks!
# DATA DECLARATION
.data
request: .asciiz "Enter an integer:\n"
sumLine: .asciiz "The sum is: "
aList: .asciiz "The array contains the following: \n"
return: .asciiz "\n"
array: .word 0
aLength: .word 10
input: .word 0
count: .word 0
count2: .word 0
count3: .word 0
sum: .word 0
next: .word 0
first: .word 0
one: .word 1
# PROGRAM CODE
.text
.globl main
# PROGRAM EXECUTION
#--------------------------------------------------------------------------
# Procedure main
# Description: Initializes registers and prints the final sum.
# parameters: $s0 = address of array, $t0 = length
# return value: $v0 = sum
# registers to be used: $s0, $t0, $t1, $t2, $t4, $t5, $v0
#--------------------------------------------------------------------------
main:
la $s0, array # s0 = array
lw $t0, aLength # t0 = aLength
lw $t1, count # t1 = count
lw $t2, input # t2 = input
lw $t3, count2 # t3 = count2
lw $t4, count3 # t4 = count3
lw $t5, sum # t5 = sum
lw $t6, first # t6 = first
lw $t7, next # t7 = next
lw $t9, one # t9 = one
beq $t1, $zero, readArray # if count=0, goto readArray procedure
la $a0, sumLine # load line to print
li $v0, 4 # print sum output line
syscall
lw $a0, sum # load sum to print
li $v0, 1 # print sum
syscall
la $a0, return # load line to print
li $v0, 4 # print return line
syscall
la $a0, aList # load line to print
li $v0, 4 # print the array list line
syscall
j printArray
#--------------------------------------------------------------------------
# Procedure readArray
# Description: Reads integers from the keyboard.
# parameters: $s0 = address of array, $t0 = length
# return value: --------
# registers to be used: $v0, $a0, $t0, $t1, $t2, $s0
#--------------------------------------------------------------------------
readArray:
beq $t1, $t0, sumSmallerThanFirst # if t1=t0 (count = aLength) goto sum procedure
la $a0, request # load line to print
li $v0, 4 # print request line
syscall
li $v0, 5 # read integer from keyboard
syscall
sw $v0, input # store integer to input
lw $t2, input # t2 = input
sw $t2, 0($s0) # array[i] = t2
addi $s0, $s0, 4 # increment array (i++)
addi $t1, $t1, 1 # increment count (count+1)
sw $t1, count # store count to t1
beq $t1, $t9, store # if t1=t9 (count = one) goto store
j readArray
store:
lw $t6, 0($s0) # t6 = array[i]
sw $t6, first # t6 = first
j readArray
#--------------------------------------------------------------------------
# Procedure sumSmallerThanFirst
# Description: Sums the inputted integers if they are < the first integer.
# parameters: $s0 = address of array, $t0 = length
# return value: ----------
# registers to be used: $s0, $t0, $t3, $t5, $t6, $t7, $t8, $0
#--------------------------------------------------------------------------
sumSmallerThanFirst:
la $s0, array
beq $t3, $t0, main # if count=length, goto main
lw $t7, 0($s0) # t7 = array[i]
sw $t7, next # t7 = next
slt $t8, $t7, $t6 # if t7<t6, t8=1
addi $s0, $s0, 4 # array[i++]
addi $t3, $t3, 1 # count+1
sw $t3, count2 # store count2 to t3
beq $t8, $zero, sumSmallerThanFirst # if t8=0, goto top sum
add $t5, $t5, $t7 # t5=t5+t6 (sum = sum + array[i])
sw $t5, sum # store sum to t5
j sumSmallerThanFirst
#--------------------------------------------------------------------------
# Procedure printArray
# Description: Prints out the array of inputted integers.
# parameters: $s0 = address of array, $t0 = length
# return value: -------------
# registers to be used: $v0, $t0, $t4, $t6, $s0
#--------------------------------------------------------------------------
printArray:
beq $t4, $t0, Exit # if count=length, goto Exit
lw $t7, 0($s0) # t7 = array[i]
sw $t7, next # t7 = next
lw $a0, next # load array[i] to print
li $v0, 1 # print array[i]
syscall
la $a0, return # load line to print
li $v0, 4 # print return line
syscall
addi $s0, $s0, 4 # array[i++]
addi $t4, $t4, 1 # count+1
sw $t4, count3 # store count3 to t4
j printArray
Exit:
jr $ra # return
in the same position as you on what i think is the exact same assignment.
regarding the array....
if you defined array as space it'll give you some weird issues... If you define it as word. You won't have such problem. I guess this is because of the difference alignment for space and word in the kernel because I did notice the different operation in the kernel level.
however... regarding the sum.... i keep getting ridiculous answers, mainly either 0, 1, or -1.

C to MIPS translation

Trying to convert this c code into MIPS and run it in SPIM.
int A[100], B[100];
for(i=1; i<100; 1++){
A[i] = A[i-1] + B[i];
}
So far this is what I have.
# comments are delimted by has marks
.data
A: .word 0:100 # array of 12 integers
B: .word 0:100 # array of 12 integers
.text
main:
li $v0, 1 # load the value "1" into register $v0
li $t0, 1 # load the value "1" into register $t0
li $t1, 100 # load the value "100" into register $t1
blt $t0, $t1, loop # branches to Loop if $t0 < 100
la $t9, B
la $t8, A
loop:
sll $t0, $t0, 2
add $t2, $t9, $t0
lw $s4, 0($t9)
add $t3, $t0, -1
add $t4, $t8, $t3
lw $s5, 0($t4)
add $t5, $t2, $s5
add $t6, $s0, $t0
sw $t7, 0($t5)
addi $t0, $t0, 1
li $v0, 1 # system call for print_int
move $a0, $t0 # the sum to print
syscall # print the sum
When running in SPIM I get the following errors:
Exception occurred at PC=0x00400040
Bad address in data/stack read: 0x00000004
Exception occurred at PC=0x0040004c
Unaligned address in inst/data fetch: 0x00000003
Exception occurred at PC=0x00400058
Bad address in data/stack read: 0x00000000
Attempt to execute non-instruction at 0x0040006c
Some direction would be nice. Thanks
You are branching to loop (blt $t0, $t1, loop) before you initialize the pointers to A and B. You need to move the blt $t0, $t1, loop to the end of your code, not have it at the beginning.
I hate to do this, but there are too many things wrong to list them all. Try this:
.data
A: .word 0:100 # array of 100 integers
B: .word 0:100 # array of 100 integers
.text
main:
li $t0, 4 # load the value "1" into register $t0
li $t1, 400 # load the value "100" into register $t1
la $t9, B
la $t8, A
loop:
add $t2, $t9, $t0 # $t2 = B + i
lw $s4, 0($t9) # $s4 = B[i]
add $t3, $t0, -4 # $t3 = i - 1
add $t4, $t8, $t3 # $t4 = A + i - 1
lw $s5, 0($t4) # $s5 = A[i - 1]
add $t5, $t8, $t0 # $t5 = A + i
add $t6, $s4, $s5 # $t6 = B[i] + A[i - 1]
sw $t6, 0($t5) # A[i] = $t6
addi $t0, $t0, 4 # i++
li $v0, 1 # system call for print_int
move $a0, $t6 # the sum to print
syscall # print the sum
blt $t0, $t1, loop # branches to Loop if $t0 < 100
Right off the bat, s1 and s2 should be initialized to the stack-based (I assume) address of your arrays.

Resources