I have to print an array in mips, but I have to work with some given code that I'm not allowed to change.
As of right now it is printing the correct amount of times, but it prints out a huge number that isn't what I am inputting for the numbers in the list. Everything in the following code is given besides what I've written under printList. Can someone help me fix this or at least steer me in the right direction? Any tips for the remaining functions would be welcome too.
.data
original_list: .space 100
sorted_list: .space 100
str0: .asciiz "Enter size of list (between 1 and 25): "
str1: .asciiz "Enter one list element: \n"
str2: .asciiz "Content of original list: "
str3: .asciiz "Enter a key to search for: "
str4: .asciiz "Content of sorted list: "
strYes: .asciiz "Key found!"
strNo: .asciiz "Key not found!"
.text
#This is the main program.
#It first asks user to enter the size of a list.
#It then asks user to input the elements of the list, one at a time.
#It then calls printList to print out content of the list.
#It then calls inSort to perform insertion sort
#It then asks user to enter a search key and calls bSearch on the sorted list.
#It then prints out search result based on return value of bSearch
main:
addi $sp, $sp -8
sw $ra, 0($sp)
li $v0, 4
la $a0, str0
syscall
li $v0, 5 #read size of list from user
syscall
move $s0, $v0
move $t0, $0
la $s1, original_list
loop_in:
li $v0, 4
la $a0, str1
syscall
sll $t1, $t0, 2
add $t1, $t1, $s1
li $v0, 5 #read elements from user
syscall
sw $v0, 0($t1)
addi $t0, $t0, 1
bne $t0, $s0, loop_in
move $a0, $s1
move $a1, $s0
jal inSort #Call inSort to perform insertion sort in original list
sw $v0, 4($sp)
li $v0, 4
la $a0, str2
syscall
la $a0, original_list
move $a1, $s0
jal printList #Print original list
li $v0, 4
la $a0, str4
syscall
lw $a0, 4($sp)
jal printList #Print sorted list
li $v0, 4
la $a0, str3
syscall
li $v0, 5 #read search key from user
syscall
move $a3, $v0
lw $a0, 4($sp)
jal bSearch #call bSearch to perform binary search
beq $v0, $0, notFound
li $v0, 4
la $a0, strYes
syscall
j end
notFound:
li $v0, 4
la $a0, strNo
syscall
end:
lw $ra, 0($sp)
addi $sp, $sp 8
li $v0, 10
syscall
#printList takes in a list and its size as arguments.
#It prints all the elements in one line.
printList:
move $t3, $0
loop1:
sll $t4, $t3, 2
add $t4, $t4, $s1
li $v0, 1
move $a0, $t4
syscall
sw $v0, 0($t1)
addi $t3, $t3, 1
bne $t3, $s0, loop1
jr $ra
#inSort takes in a list and it size as arguments.
#It performs INSERTION sort in ascending order and returns a new sorted list
#You may use the pre-defined sorted_list to store the result
inSort:
#Your implementation of inSort here
jr $ra
#bSearch takes in a list, its size, and a search key as arguments.
#It performs binary search RECURSIVELY to look for the search key.
#It will return a 1 if the key is found, or a 0 otherwise.
#Note: you MUST NOT use iterative approach in this function.
bSearch:
#Your implementation of bSearch here
jr $ra
Related
I am working on a program that calculates combinations in MIPS. The user enters the size of the pool, and number of balls to pick from it, and the program should output the total combinations. The program correctly calculates the numerator, but when it comes to dividing the numerator (n!) by the denominator, which is also correctly calculated, the combinations number is wrong.
I think something goes wrong with $t2 when it is used in main, but not sure what exactly or how to fix it.
.data
message1: .asciiz "Enter input for the size of the large pool: "
message2: .asciiz "Enter input for # of balls to be selected from large pool: "
message5: .asciiz "The numerator is: "
newline: .asciiz "\n"
.text
.globl main
main:
# Call on function messages
jal messages
# Calculate factrl for # from large pool size
move $a0, $s2
jal factrl # Call on factrl function
move $t5, $v0
# Find (n-k) for large pool
sub $t0, $s1, $s2
# Intialize $t2 to 1
li $t2, 1
# Call function while for large pool
move $a1, $s1
move $a2, $t0
jal while
move $v0, $t2
# Find probability for large
move $a0, $v0
move $a1, $t0
jal combination
move $t7 $v0
li $v0, 4
la $a0, newline
syscall
li $v0, 1
add $t7, $t7, $zero
syscall
# Exit Program
li $v0, 10
syscall
messages:
# Request size of large pool
li $v0, 4
la $a0, message1
syscall
# Get input for size of large pool
li $v0, 5
syscall
# Store input in register
move $s1, $v0
# Request # selected from large pool
li $v0, 4
la $a0, message2
syscall
# Get input for # of large pool
li $v0, 5
syscall
# Store input in register
move $s2, $v0
li $v0, 4
la $a0, newline
syscall
jr $ra
factrl:
sw $ra, 4($sp) # save the return address
sw $a0, 0($sp) # save the current value of n
addi $sp, $sp, -8 # move stack pointer
slti $t0, $a0, 2 # save 1 iteration, n=0 or n =1; n!=1
beq $t0, $zero, L1 # not less than 2 , calculate n(n - 1)!
addi $v0, $zero, 1 # n=1; n!=1
jr $ra # now multiply
L1:
addi $a0, $a0, -1 # n = n - 1
jal factrl # now (n - 1)!
addi $sp, $sp, 8 # reset the stack pointer
lw $a0, 0($sp) # fetch saved (n - 1)
lw $ra, 4($sp) # fetch return address
mul $v0, $a0, $v0 # multiply (n)*(n - 1)
jr $ra # return value n!
while:
addi $sp, $sp, -8 # allocate space in stack
sw $ra, 4($sp)
sw $a1, 0($sp) # store the value of $s1 on the stack
beq $a1, $a2, numerator
mult $t2, $a1 # multiply val x n
mflo $t3
move $t2, $t3
addi $a1, $a1, -1 # n = n-1
j while
numerator:
li $v0, 4
la $a0, message5
syscall
# Print the numerator
li $v0, 1
move $a0, $t2
syscall
lw $a1, 0($sp)
addi $sp, $sp, 8 # reset stack pointer
jr $ra
combination:
div $v0, $a1, $a0
jr $ra
exit:
li $v0, 10
syscall
I am currently trying to figure out why my mars program for creating an array is getting stuck in an infinite loop. I am trying to create an array using different functions and in the create array function the program is supposed to jump into a get number function and return the value to store it into the array but the counter seems to not be decrementing and it just keeps asking for an element for the array. Here is the code:
.data
str5: .asciiz "Please enter a number of elements for the array between 0 and 20: "
str6: .asciiz "Please enter an element: "
array: .word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.text
main:
begin:
li $v0, 4
la $a0, str5
syscall
jal readnum
add $a0, $v0, $0
jal verify
add $a0, $v0, $0
jal createarray
la $s1, array
jal printarray
li $v0, 10
syscall
printarray:
createarray:
add $t0, $ra, $0
add $s0, $a0, $0
add $t9, $0, $0
la $s1, array
loop:
beq $s0, 0, done
li $v0, 4
la $a0, str6
syscall
jal readnum
add $t1, $v0, $0
sw $t1, 0($s1)
addi $s1, $s1, 4
addi $s0, $s0, -1
addi $t9, $t9, 1
j loop
done:
add $ra, $t0, $0
jr $ra
verify:
add $s0, $a0, $0
bge $s0, 20, begin
ble $s0, 0, begin
add $v0, $s0, $0
jr $ra
readnum:
li $v0, 5
syscall
jr $ra
EDIT: After re-reading the code, what is causing the error is actually the following code:
jal printarray
You never did the following code in printarray:
jr $ra
So, it would go back down to the other functions.
Use the $sp (the proper way to handle the $ra when calling functions within functions)
The following segment is the cause of the problem:
syscall
jal readnum
add $t1, $v0, $0
Moreso specifically the jal call. Calling a function within a function requires some more steps to be taken place.
First, understand what the jal instruction is doing. The jal instruction, put simply, marks where you currently are and stores it in the $ra register. Then, it will jump to that function.
But there's a problem: you are already wishing for the $ra register to remember where you once were because you, in fact, called createarray!
So, you called createarray, making $ra store where you once were, then within that function you called readnum, making $ra store where you are in createarray. **But now, you have lost where you once were before called createarray. So, it will keep looping back to what $ra used to be, which is inside your createarray function.
Fortunately, the $sp register is just what you need
How to use the $sp register
To store where we are, we push to the stack:
addi $sp, $sp, -4 # by convention, we use negative numbers when pushing
sw $ra, ($sp)
To get where we once were after we called the function (which replaced our $ra in the first place), we pop the stack:
lw $ra, ($sp)
addi $sp, $sp, 4 # by convention, we use positive numbers when popping
So in the grand scope of things, here is what you do:
# push to the stack
addi $sp, $sp, -4
sw $ra, ($sp)
jal theFunctionWeWantToCallInOurFunction
# pop the stack, get back our $ra
lw $ra, ($sp)
addi $sp, $sp, 4
Let's apply this solution to your codebase:
.data
str5: .asciiz "Please enter a number of elements for the array between 0 and 20: "
str6: .asciiz "Please enter an element: "
array: .word 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.text
main:
begin:
li $v0, 4
la $a0, str5
syscall
jal readnum
add $a0, $v0, $0
jal verify
add $a0, $v0, $0
jal createarray
la $s1, array
jal printarray # comment off this line and you won't have an infinite loop
li $v0, 10
syscall
printarray:
createarray:
add $t0, $ra, $0
add $s0, $a0, $0
add $t9, $0, $0
la $s1, array
loop:
beq $s0, 0, done
li $v0, 4
la $a0, str6
syscall
# store where we wish to come back to so that $ra can be overriden without losing data.
addi $sp, $sp, -4
sw $ra, ($sp)
# call the function. jal will replace our current $ra
jal readnum
# retrieve what our $ra once was
lw $ra, ($sp)
addi $sp, $sp, 4
add $t1, $v0, $0
sw $t1, 0($s1)
addi $s1, $s1, 4
addi $s0, $s0, -1
addi $t9, $t9, 1
j loop
done:
add $ra, $t0, $0
jr $ra
verify:
add $s0, $a0, $0
bge $s0, 20, begin
ble $s0, 0, begin
add $v0, $s0, $0
jr $ra
readnum:
li $v0, 5
syscall
jr $ra
So ive been able to create an array that is the size of what the user chooses and the code proceeds to Sort just fine when debugging, the issue is for some reason its not getting past Sort and into swap and im not quite sure why. In the debugger it seems to read the code to swap but then skips over it and repeats sort in an infinite loop. Am i doing something wrong?
.data
count: .word 0
prompt1: .asciiz "Enter the array size \n"
prompt2: .asciiz "Enter integers to fill the array \n"
prompt3: .asciiz "Sorted Array: "
.text
li $v0, 4
la $a0, prompt1
syscall
li $v0, 5
syscall
sw $v0, count
sll $a0, $v0, 2
li $v0, 9
syscall
move $t0, $v0
lw $t1, count
loop:
li $v0, 4
la $a0, prompt2
syscall
li $v0, 5
syscall
beqz $v0, sort
sw $v0, 0($t0)
addi $t0, $t0, 4
sub $t1, $t1, 1
bnez $t1, loop
sort:
lw $t3, 0($t0)
lw $t4, 4($t0)
blt $t4, $t3, swap
addiu $t0, $t0, 4
addi $t1, $t1, -1
bne $t1, $zero, sort
jr $ra
swap:
sw $t3, 4($t0)
sw $t4, 0($t0)
j sort
end:
exit:
li $v0, 10
syscall
For some reason the integer values i'm putting into memory of the array of base $t0 cant be accessed later on even though when debugging i can clearly see that they are stored correctly in memory at 0($t0) and 4($t0) in the case of 2 integers. Its when i go into the passloop and attempt to load them into t6 or t7 that no value is being passed. Can someone explain why this is?
# bubble sort
.data
prompt1: .asciiz "Enter the array size \n"
prompt2: .asciiz "Enter integers to fill the array \n"
prompt3: .asciiz "Sorted Array: "
.text
.globl main
main:
la $a0, prompt1
li $v0, 4
syscall
li $v0, 5
syscall
add $t1, $zero, $v0
add $t2, $zero, $v0
sll $a0, $v0, 2
li $v0, 9
syscall
add $t0, $zero, $v0
loop:
la $a0, prompt2
li $v0, 4
syscall
li $v0, 5
syscall
beqz $t1, mainloop
sw $v0, ($t0)
addiu $t0, $t0, 4
subiu $t1, $t1, 1
bnez $t1, loop
mainloop:
subi $a1,$t2,1
blez $a1,done
li $t3,0
jal passloop
beqz $t3,done
subi $t2,$t2,1
j mainloop
#print sorted data, code still needed. Need to fix accessing issue first
done:
j end
passloop:
lw $t6,0($t0)
lw $t7,4($t0)
bgt $t6,$t7,swap
next:
addiu $t0,$t0,4
subiu $a1,$a1,1
bgtz $a1,passloop
jr $ra
swap:
sw $t6,4($t0)
sw $t7,0($t0)
li $t3,1
j next
end:
li $v0,10
syscall
I am doing my homework and it says that I have to ask user for how many members they want to be present in the array. Then the user should enter the number in their array and then the program prints the array. I cannot print contents from my array in the console window.
Here is my code:
.data
max: .word -9999
array: .space 12
message1: .asciiz "Enter an integer:\n"
message2: .asciiz "Specify how many numbers should be stored in the array (atmost 8): \n"
message3: .asciiz "The array content is: \n"
message4: .asciiz "The maximum is: \n"
message5: .asciiz "They have the same maximum.\n"
message6: .asciiz "The first array has a larger maximum.\n"
message7: .asciiz "The second array has a larger maximum.\n"
.text
.globl main
main:
lw $s1, max
la $s3, array
li $s2, 3
la $a0, message2
li $v0, 4
syscall
li $v0, 5
syscall
move $t0, $v0
blt $t0, $s2, Read
Read:
la $a0, message1
li $v0, 4
syscall
li $v0, 5
syscall
move $t1, $v0
sw $t1, 0($s3)
addi $s3, $s3, 4
addi $t0, $t0, -1
bgt $t0, $zero, Read
j Print
#blt $t0, $s2, Print
Print:
la $a0, message3,
li $v0, 4
syscall
jr $ra
Thanks for the help.
When you enter Print you've got the end of the array plus 4 in $s3, so you could do something like this:
$s2 = ADDRESSOF(array)
while ($s2 != $s3) do
print_int($s2[0]) // syscall 1
print_character(' ') // syscall 11
$s2 += 4
end while
This is pseudo-code to illustrate the logic; I'll leave the actual assembly implementation to you since it's your assignment.
(By the way, this: la $a0, message3, is a typo. There shouldn't be a comma at the end of that line)