Mips, continuous user input - loops

How would I go about asking a user for continuous input? Basically I want to capture only numbers greater than 0, anything less than 0 I want to print an error message followed by the enter number message.

How would you go about solving this in high-level language pseudocode? One way is -
while true
print("Enter a number: ")
n = read_a_number()
if n < 0
print("Error. Negative number")
else
# process the non-negative number (>= 0)
# detect when to break while loop
Once the above is clear, it is fairly easy to translate this to MIPS.
.data
prompt: .asciiz "Enter a number: "
error: .asciiz "Error. Negative number\n"
.text
while:
la $a0, prompt # print prompt to enter a number
li $v0, 4 # $v0 = 4 to print string with address in $a0
syscall
li $v0, 5 # to read an int. Read in $v0
syscall
bltz $v0, negative # is the input negative?
j non_negative # else, handle non_negative
negative:
la $a0, error # print error
li $v0, 4
syscall
j next # and goto 'next'
non_negative:
# process the non-negative number (>= 0)
j next # and goto 'next'
next:
# detect when to break while loop (or do that at the start of the loop)
j while # continue loop
after_while: # after the loop
li $v0, 10 # $v0=10 to exit
syscall

Related

from java to MIPS assembly for a simple while loop [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 25 days ago.
Improve this question
i need to convert a code from java to assembly, but it only prints the first message. but the last two message dosent print neither the message nor the numbers of the result.
the two code in java and assembly are that i wrote as follow :
the code in java:
/**
* this program count how many 10s can be in a givin number the return the extra or the remain that less than 10
*/
Scanner input=new Scanner(System.in);
System.out.println("enter num: ");//print input message
int num=input.nextInt();// user input
int numOf10=0;//counter
while(num>9){ //start of while loop
num-=10;//subtruct 10 from the input number
numOf10++;//add one to the counter
}
System.out.println("number of 10 is: "+numOf10);//print message contain
System.out.println("the remain: "+num);//print message contain
////////////////////////////////////////////////////////////////////////////////////
the code in assembly:
.data
EnterMessage: .asciiz"Enter the number:\n "
ResultMessage: .asciiz"number of 10 is:\n"
remainMessage: .asciiz"the remain:\n "
.text
main:
#ask user to enter input
li $v0,4
la $a0,EnterMessage
syscall
#read user input
li $v0,5
syscall
#save input
move $t0,$v0
#creat variables
#$t2=9
addi $t2,$zero,9
#counter=$t3=0
addi $t3,$zero,0
#jal loop
#while loop
loop:
ble $t1,$t2,exit
subi $t0,$t0,10
addi $t3,$t3,1
j loop
print:
#print ResultMessage num
li $v0,1
move $a0,$t3
syscall
#print ResultMessage
li $v0,4
la $a0,ResultMessage
syscall
#print remainMessage num
li $v0,1
move $a0,$t0
syscall
#print remainMessage
li $v0,4
la $a0,remainMessage
syscall
#close the program
exit:
#end
li $v0,10
syscall
Your problem is here:
ble $t1,$t2,exit
There are a couple of problems here. First, exit leads to:
#close the program
exit:
#end
li $v0,10
syscall
So you've jumped to the end without doing anything.
Second, you've chosen $t1 as one of your registers for the compare, which you never set up. So its value is currently unknown (most likely the kernel or OS or whatever zeroed all your registers prior to main but it's not a good practice to assume that.)
Let's think about what's being asked:
while(num>9){ //start of while loop
num-=10;//subtruct 10 from the input number
numOf10++;//add one to the counter
}
When translating a high-level language to assembly we don't have to do everything the same way it was written in the source language. In terms of goto we can think of this as:
loop_begin:
if (num <= 9) goto loop_exit;
num -= 10;
numOf10++;
goto loop_begin;
loop_exit:
You've got the right idea for the most part. The nice thing about MIPS is that the branching syntax isn't nearly as obtuse as other assembly languages, since you don't have to remember whether carry clear means less than or greater than etc.
loop:
ble $t0,$t2,print # if $t0 (num) <= 9 goto print
subi $t0,$t0,10 # num = num - 10
addi $t3,$t3,1 # counter++
j loop # goto loop
Edit: Fixed typo in comments in last section

MIPS: Writing code to ask a user for an input and printing responses

I am really struggling with assembly language and, unfortunately, have gotten into the habit of treating it more like an assignment than a learning objective. I am now being tasked with writing some code that asks a user for an input (in this case, an integer) and then prints a response based on that integer.
Directions:
Ask a user for an integer-- if the integer is '8', print "Great!". If it's not 8, print "Try again" and then ask them to submit one more time. If they don't print the integer, '8', on the second attempt, simply type game over.
.data
message: .asciiz "Please enter an integer:"
correct_str: .asciiz "Great!\n"
incorrect_str: .asciiz "Game over! \n"
li $t0,8 #this is the correct answer
li $t1,0 # creates a counter of two attempts
loopcheck:
la $a0, message # prompt user
li $v0, 4
syscall
li $v0, 5
syscall
move $s1, $v0 # s1 becomes what user inputs
#this is where we check to see if it's 8, printing game over or looping again and printing game over if not correct on second time
printGameOver:
la $a0, wrong_str
li $v0, 4
syscall
j done
printright:
la $a0, right_str
li $v0, 4
syscall
done: #exit
li $v0, 10
syscall

How do I get an INTEGER and turn that into an ARRAY of separate single digit integers in MIPS?

Okay so I have an issue. I want to get an integer and turn it into an array of single-digit integers in MIPS but I'm not sure how to go about that.
Can you guys help me? I know how to do this in every other language except this one...
Example:
I want to the integer 32325
to be an array where A[0] = 3, A[1] = 2, A[2] = 3, ...
Can you please help me? I've been stumped for a while!
This is what I have so far...
.data
prompt: .asciiz
msg: .asciiz
array: .space 24 #6 digit number
.text
li $v0, 4 #print out
la $a0, prompt1
syscall
li $v0, 5 #take in int
syscall
la $a0, array# Set address t0 to be the array
I have no idea about MIPS, but the algorithm is quite simple
Divide the number by 10, as long as it is != 0 ... the reminders (in reverse order) are the digits. easiest way to store them would be the stack, since pop'ing them will bring them into correct order again:
counter=0
while (number !=0) {
push number%10
number /= 10
counter++
}
while (counter>0) {
pop number
store/display it
counter--
}

How to calculate the sum of even integers between two values in MIPS?

I am confused on how to convert C code to MIPS. I seem to to get the loops confused and I think I am possibly using the wrong command. The C code I made to do this is as follows:
int main()
{
int x, y;
int sum = 0;
printf("Please enter values for X and Y:\n ");
scanf("%d %d",&x,&y);
if (x > y)
{
printf("\n** Error");
exit(0);
}
while (x <= y)
{
if (x%2 == 0)
sum += x;
x++;
}
printf("\nThe sum of the even integers between X and Y is: %d\n\n",sum);
return 0;
}
My attempt at the MIPS translation is as follows:
.data
Prompt: .asciiz "Please enter values for X and Y:\n"
Result: .asciiz "The sum of the even integers between X and Y is: \n"
.text
li $v0,4 #load $v0 with the print_string code.
la $a0, Prompt #load $a0 with the message to me displayed
syscall
li $v0,5 #load $v0 with the read_int code for X
syscall
move $t0,$v0
li $v0,5 #load $v0 with the read_int code for Y
syscall
move $t1, $v0
while:
slt $t2, $t1,$t0 #$t1 = y $t0 = x
li $t3,2
div $t2,$t3
beq $t2,$0,else
add $s1,$s1,$t0 #s1 = s1 + x
addi $t0,$t0,1 #x++
j while
else:
li $v0,4
la $a0, Result
syscall
move $a0,$s1
li $v0,1
syscall
I think my error is in the loop in my MIPS code. My result keeps producing zero and I think my code is checking the loop and then just jumping to my else statement.
After further work, I got it to calculate the sum of all integers and I'm not exactly sure why it is doing so. Here is my most recent update:
while:
sle $t2, $t0,$t1 #$t1 = y $t0 = x
li $t3,2 #t3 = 2
div $t2,$t3 #$t2/2
beq $t2,$0, else #if ($t2/2 == 0), jump to the else, otherwise do else
add $s1,$s1,$t0 #s1 = s1 + x
addi $t0,$t0,1 #x++
j while
So now, if I enter 1 and 5, it calculates 1 and 3 is gives me 6 instead of just the even sum which should be just 2.
To answer my own question, the main confusion was with the the branches. I now understand that they kind of work like opposites so for example, I had to set the "beq" in my while loop to bnez so it would do the calculations when $t2 was != 0. Another minor fix was adding the increment outside of the loop. So, when $t2 != 0, I jump to my "else" which then incremented to find the next number. However, if the remainder was 0, it did the math of sum=sum + x. In conclusion, the main confusion came from thinking opposite about the branches. I now understand that if I wanted to say:
while(a1 < a2)
I would have to write it as
while:
bgeu $a1,$a2, done
addi "whatever"
b while
done:
do done stuff
Before this understanding, I was writing it as ble $a1,$a2,done and that is not the way it is to be typed. Logically, that says if a1 < a2...but it is really saying if a1 < a2, jump to the "done" and skip calculations. So I just had to think opposite.

MIPS Assembly creating character checker

I am looking for help on how to take a string from the user and then output the number of times each letter was used in the string.
Pseudo code
string "Please enter a string:"
take string and save into an array,
check for ascii duplicates of character values and then output when corresponding letter is output.
example: Hello World
A:
B:
C:
D: 1
E: 1
...
H: 1
...
W: 1
code
.data
intro: .asciiz "Letter Checker Program"
question: .asciiz "\nPlease enter a string for evaluation: "
string: .space 1024
alphabet: .space 26
.text
main:
jal setup
#jal analyze
#jal results
li $v0, 10
syscall
setup:
li $v0, 4 # outputing name and program information
la $a0, intro
syscall
li $v0, 4 # asksing for string input
la $a0, question
syscall
li $v0, 8
la $a0, string
li $a1, 1024
syscall
jr $ra # return
analyze:
loop:
loop:
results:
What you want to do is:
Create some space (26 * 4 bytes) to store the results and fill with 0
Loop over every letter in the string and load with lb
Determine the numerical value of the letter, and thus the memory location (of step 1). Don't forget about lower and upper case letters.
Load that memory location (4 bytes, use lw), increase the value with 1, and store again with sw
Stop when you encounter 0 (not the letter '0')
In analyze, loop over every letter in the alphabet, load the corresponding memory location from step 1, and print results

Resources