MIPS program not giving the right output - loops

I am writing a program to take 10 numbers from user into .word. The program is:
.data
msg1: .asciiz"Ener the number: "
fibs: .word 0,0,0,0,0,0,0,0,0,0
.text
main:
li $t0, 0
loop: # (loop condition, TODO)
bgt $t0,9 ,exit
li $t1, 0 # i = 0
la $a0,msg1 # display prompt string
li $v0,4
syscall
li $v0,5 # read 1st integer into $t0
syscall
move $t2,$v0
lw $t2, fibs($t1) # fib = fibs[i]
addi $t1, $t1, 4 # i++ <= +4
j loop
exit:
move $a0,$t1 # output sum
li $v0,1
syscall
li $v0, 10 # exit the program
syscall
However, the loop never ends and continuously takes the input...I want it to stop and show me the numbers I have input after the 10 integers are entered

Related

C to MIPS Decimal to Binary Converter Using Recursion

I am new to MIPS and I wrote a basic format of what I think the code from the C file I wrote is the equivalent to of the MIPS.
My assignment is to convert the following C file which I wrote into a direct translation of what the MIPS is supposed to be. My current C code is :
#include <stdio.h>
int d2b(int d)
{
if(d == 0)
{
return;
}
else
{
return (d %2 + 10 * d2b(d/2));
}
}
int main()
{
int d = 99;
int b;
b = d2b(d);
printf("Input => %d \n", d);
printf("Output => %d ", b);
return;
}
So far I have the following :
.data
msg1 .asciiz “Number is “
msg2 .asciiz “\nConverted to \n“
.text
.globl main
main:
li $v0, 4
la $a0, msg1
syscall
li $v0, 5 #Exit syscall
syscall
add $a0, $v0, $zero
jal fact
add $a0, $v0, $zero
li $v0, 1
syscall
li $v0, 10
la $a0, msg2
syscall
fact:
li $t0 0 #load 0
beq $a0, $t0, skip #test n
li $v0 0
jr $ra
skip:
subu $sp, $sp, 32
sw $ra 20($sp)
sw $fp, 16($sp)
addiu $fp, $sp, 28
sw $a0, 0($fp) #save n
li $t1 2 #load 2
divu $a0 $t1 #n / 2
mfhi $t2 #remainder
mflo $t3 #quotient
move $a0, $t3 #n = quotient
addi $v0, $a1, 10
jal fact
lw $a0, 0($fp) #restore n
multu $v0, $a0
lw $ra, 20($sp)
lw $fp, 16($sp)
addiu $sp, $sp, 32
jr $ra
My main problem is not knowing how to use syscall and not really understand a recursive function in MIPS. Please point out my mistakes and errors!
your MIPS syscalls are in this section
li $v0, 4
la $a0, msg1
syscall
li $v0, 5 #Exit syscall
syscall
add $a0, $v0, $zero
jal fact
add $a0, $v0, $zero
li $v0, 1
syscall
li $v0, 10
la $a0, msg2
syscall
They are commented incorrectly
In a MIPS syscall $v0 holds the "syscall function" or in English, the service you want the operating system to perform. There's a table of them here.
$a0 will hold the first parameter passed to the call. To set this parameter, one technique is to add the input value to zero storing the result into $a0 That's why you have so many lines like this
add $a0, $v0, $zero # this adds $v0 to the number zero and storing in $a0
Finally, the syscalls you are using are (4 => print String, 5 => read integer, 1 => print integer, and 10 => exit)
So a properly commented example of your code would be
la $a0, msg1 # load string as parameter
li $v0, 4 # load operation "print string"
syscall # request "print string" for msg1
li $v0, 5 # load operation "read integer"
syscall # request "read integer"
add $a0, $v0, $zero # load the read integer into $a0
jal fact
add $a0, $v0, $zero # load the value of $v0 into $a0
li $v0, 1 # load operation "print integer"
syscall # request "print integer"
As you can see, my confusion comes not from your ability to use syscalls, but from your description of what you think you are using the syscalls to do.
You state you want to print a binary number like 01001010 from a decimal input. This typically involves breaking the decimal number down, in a loop, printing out a zero or one in each of the binary number places. As this would require a loop for each placeholder in the binary number, it doesn't seem that a single call to "print integer" would be possible (unless the input was limited to only the decimal '1' and '0', or the input is limited to such a small number that it's binary representation, represented in decimal format is less than max_int).
So for an input of 5, the desired output would be 101, and that would be 3 calls to print, in the order of '1', '0', '1'. I believe this approach of printing the digits in a loop will give you greater success, and will permit you to print every positive decimal number inputted.
In short, I think your command of syscall is fine, but you're still struggling with how to do loops and solve problems in assembly. Try to figure out how you would determine the digits in the needed order by hand, using a pencil and paper, and then attempt to code that into your program.

saving a value inside a mips loop

I've just started to learn MIPS, and as part of our assignment, I'm trying to save a counter value that runs inside a loop.
So, I was able to exit the loop, thanks to Michael. But now the counter will not increase, I noticed that it won't enter the incount label.
.text
.globl main
main:
# get string from user
la $a0, str1 # load the addr of the given string into $a0.
li $v0, 4 # 4 is the print_string syscall.
syscall # do the syscall.
li $v0, 8 # take in input
la $a0, buffer # load byte space into addr
li $a1, 10 # allot the byte space for the string
move $t0, $a0 # save the string into $to
syscall
# get char from user
la $a0, char1 # load the addr of the given char into $a0.
li $v0, 4 # 4 is the print_string syscall.
syscall # do the syscall.
li $v0, 8 # take in input
la $a0, buffer # load byte space into addr
li $a1, 10 # allot the byte space for the char
move $t1, $a0 # save the char into $t1
syscall
addi $s2, $zero,0 # s2 holds the counter
loop:
lb $t3, ($t0)
beq $t3, $t1, incount # go to incount if char was found
beqz $t3, exit # go to exit if we arrived to the end of the string
addi $t0, $t0, 1 # incrase t3 by 1
j loop # go to loop
incount:
addi $s2, $s2, 1 # increase the counter by 1
addi $t0, $t0, 1 # incrase char pos by 1
j loop # go back to loop
exit:
la $a0, ($s2) # counter to be printed
li $v0, 1 # 1 is the print_int syscall.
syscall
li $v0, 10 # return control to SPIM OS
syscall
.data
buffer: .space 10
str1: .asciiz "Please enter your string: "
char1: .asciiz "Now, please enter your char of choice: "
# end countchar.s
Thanks in advance
You've placed your exit routine in the .data section, which is why you're getting the "invalid program counter value" error message. All code needs to be in the .text section.

read and sum array of integers in assembly

.data
prompt1: .asciiz "\n\n Enter an integer please:"
array: .space 24
linefeed: .asciiz "\n"
enterkey: .asciiz "Press any key to end program."
.text
main:
li $s0, 0
for:
bge $s0, 6, end_for
li $v0, 4 #syscall to print string
la $a0, prompt1 #address of string to print
syscall
li $v0, 5 #syscall to read an integer
syscall
move $t1,$v0
sw $t1,array($t0) #save the number to read into array
addi $t0,$t0,4
addi $s0,$s0,1
j for
end_for:
# print out a line feed
li $v0,4 # code for print_string
la $a0,linefeed # point $a0 to linefeed string
syscall # print linefeed
# wait for the enter key to be pressed to end program
li $v0,4 # code for print_string
la $a0,enterkey # point $a0 to enterkey string
syscall # print enterkey
# wait for input by getting an integer from the user (integer is ignored)
li $v0,5 # code for read_int
syscall #get int from user --> returned in $v0
# All done, thank you!
li $v0,10 # code for exit
syscall # exit program
this is my code.I am trying to store 6 integers in an array and then read again the array of integers and sum them and then printing the sum.I apologize for my bad english
It would be basically the same loop you have just written, but instead of writing the number to the array you would have to read it from the array and sum the values.
E.g.:
li $s0, 0
li $a0, 0
li $t0, 0
forsum:
bge $s0, 6, end_forsum
lw $t1,array($t0) # Load the number from array
addu $a0, $a0, $t1 # Compute the sum
addi $t0,$t0,4
addi $s0,$s0,1
j forsum
end_forsum:
li $v0,1
syscall # Print sum
You can also compute the sum while reading the values from the user input...

Printing an array of float numbers in MIPS

I am a anew user to MIPS and I am having problems in printing an array of floating point numbers that I am taking in from the user and also I am having problems with finding the most repeated floating point number.
Here is the code in which I am able to take in user input but not able to print the array.
#data declarations: declare variable names used in program, storage allocated in RAM
.data
max: .word 12
temp: .word 1
num: .space 96
input1: .asciiz "Enter a number:\n" #prints the statement
output1: .asciiz "The number that is repeated more often than any other is "
output2: .asciiz " with "
output3: .asciiz " repititions.\n"
output4: .asciiz "The array contains the following: \n"
.text
.globl main
main:
lw $t1, temp
lw $t2, max
Loop:
la $a0, input1 # $a0 = address of input1
li $v0, 4 # $v0 = 4 --- this is to call print_string()
syscall
li $v0, 6
syscall
la $t0, num
s.s $f0, 0($t0)
addi $t0, $t0, 8
addi $t1, $t1, 1
ble $t1, $t2, Loop
la $a0, output4
li $v0, 4
syscall
l.s $f12, 0($t0)
li $v0, 2
syscall
jr $ra
.data
max: .word 3
temp: .word 1
num: .space 96
input1: .asciiz "Enter a number:\n" #prints the statement
output1: .asciiz "The number that is repeated more often than any other is "
output2: .asciiz " with "
output3: .asciiz " repititions.\n"
output4: .asciiz "The array contains the following: \n"
.text
.globl main
main:
lw $t1, temp # loop counter
lw $t2, max # upper bound
la $t0, num # address of array
Loop:
# print input prompt
la $a0, input1
li $v0, 4
syscall
# get value from the user
li $v0, 6
syscall
# move user provided value from $f0 to array
s.s $f0, 0($t0)
# move to the next position in the array, increment loop counter
addi $t0, $t0, 4
addi $t1, $t1, 1
ble $t1, $t2, Loop
# restore loop counter, and array address for printing
lw $t1, temp
la $t0, num
# print output prompt
la $a0, output4
li $v0, 4
syscall
print_loop:
# print number from the array
l.s $f12, 0($t0)
li $v0, 2
syscall
# print space
la $a0, 32
li $v0, 11
syscall
# increment loop counter and move to next value
addi $t1, $t1, 1
addi $t0, $t0, 4
ble $t1, $t2, print_loop
Here is how it works:
Enter a number:
2.3
Enter a number:
3.14
Enter a number:
5.55
The array contains the following:
2.3 3.14 5.55

Can't print contents of array

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)

Resources