4 input MIPS Calculator - mips

Im new to MIPS and my friend practice program is a calculator, instead of allowing users to have 2 inputs(eg. 1 + 2 or 1 * 4) how do allow them to have 4 inputs (eg. 1 + 3 + 3 + 2 or 1 * 4 * 5 * 2). The code below is a working 2 input calculator how do I make it to 4?
#data
.data
prompt1: .asciiz "Type out your first number: "
prompt2: .asciiz "Type out your second number: "
prompt3: .asciiz "Type out your third number: "
prompt4: .asciiz "Type out your fourth number: "
menu: .asciiz "Now choose which of the operation you want do: 1 for add, 2 for subtract , 3 for multiply: "
resultText: .asciiz "Your final result is: "
.text
.globl main
main:
#The following block of code is to pre-load the integer values representing the various instructions into registers for storage
li $t3, 1 #This is to load the immediate value of 1 into the temporary register $t3
li $t4, 2 #This is to load the immediate value of 2 into the temporary register $t4
li $t5, 3 #This is to load the immediate value of 3 into the temporary register $t5
li $t6, 4 #This is to load the immediate value of 4 into the temporary register $t6
li $t7, 5 #This is to load the immediate value of 5 into the temporary register $t7
#asking the user to provide the first number
li $v0, 4 #command for printing a string
la $a0, prompt1 #loading the string to print into the argument to enable printing
syscall #executing the command
#the next block of code is for reading the first number provided by the user
li $v0, 5 #command for reading an integer
syscall #executing the command for reading an integer
move $t0, $v0 #moving the number read from the user input into the temporary register $t0
#asking the user to provide the second number
li $v0, 4 #command for printing a string
la $a0, prompt2 #loading the string into the argument to enable printing
syscall #executing the command
#reading the second number to be provided to the user
li $v0, 5 #command to read the number provided by the user
syscall #executing the command for reading an integer
move $t1, $v0 #moving the number read from the user input into the temporary register $t1
li $v0, 4 #command for printing a string
la $a0, menu #loading the string into the argument to enable printing
syscall #executing the command
#the next block of code is to read the number provided by the user
li $v0, 5 #command for reading an integer
syscall #executing the command
move $t2, $v0 #this command is to move the integer provided into the temporary register $t2
beq $t2,$t3,addProcess #Branch to 'addProcess' if $t2 = $t3
beq $t2,$t4,subtractProcess #Branch to 'subtractProcess' if $t2 = $t4
beq $t2,$t5,multiplicationProcess #Branch to 'multiplyProcess' if $t2 = $t5
addProcess:
add $t6,$t0,$t1 #this adds the values stored in $t0 and $t1 and assigns them to the temporary register $t6
#The following line of code is to print the results of the computation above
li $v0,4 #this is the command for printing a string
la $a0,resultText #this loads the string to print into the argument $a0 for printing
syscall #executes the command
#the following line of code prints out the result of the addition computation
li $v0,1
la $a0, ($t6)
syscall
li $v0,10 #terminate the program
subtractProcess:
sub $t6,$t0,$t1 #this adds the values stored in $t0 and $t1 and assigns them to the temporary register $t6
li $v0,4 #this is the command for printing a string
la $a0,resultText #this loads the string to print into the argument $a0 for printing
syscall #executes the command
#the following line of code prints out the result of the addition computation
li $v0,1
la $a0, ($t6)
syscall
li $v0,10 #terminate the program
multiplicationProcess:
mul $t6,$t0,$t1 #this adds the values stored in $t0 and $t1 and assigns them to the temporary register $t6
li $v0,4 #this is the command for printing a string
la $a0,resultText #this loads the string to print into the argument $a0 for printing
syscall #executes the command
#the following line of code prints out the result of the addition computation
li $v0,1
la $a0, ($t6)
syscall
li $v0,10 #terminate the program

Pretty much all you want to do is add, subtract or multiply the values from each other one right after another
addProcess:
add $t6,$t0,$t1
add $t6, $t6, $t8
add $t6, $t6, $t9
this adds the two values saving them at $t6, then adds the value at register $t6 to the value at register $t8 while again saving to $t6, then once more.
subtractProcess:
sub $t6,$t0,$t1
sub $t6,$t6, $t8
sub $t6, $t6, $t9
multiplicatioProcess:
mul $t6,$t0,$t1
mul $t6, $t6, $t8
mul $t6, $t6, $t9
Just add these where your single line is, then also add a spot at the top requesting the user enter more values
#asking the user to provide the first number
li $v0, 4
la $a0, prompt1
syscall
#the next block of code is for reading the first number provided by the user
li $v0, 5
syscall
move $t0, $v0
#asking the user to provide the second number
li $v0, 4
la $a0, prompt2
syscall
#reading the second number to be provided to the user
li $v0, 5
syscall
move $t1, $v0
#asking the user to provide the third number
li $v0, 4
la $a0, prompt3
syscall
#reading the second number to be provided to the user
li $v0, 5
syscall
move $t8, $v0
#asking the user to provide the third number
li $v0, 4
la $a0, prompt4
syscall
#reading the second number to be provided to the user
li $v0, 5
syscall
move $t9, $v0
you could also do all of this in the form of a procedure but its more advanced

Related

MIPS - Prints the input next to output

I'm learning MI trying to write a factorial program in MIPS Assembly code for which
3! = 6 (my output shows it 36)(input next to output)
4! = 24(my output shows it as 424)
Here is my code. What should I do to get rid of printing the input?
.data
num: .asciiz "\nPlease enter a number: "
num2: .asciiz"\nPlease give your second number : "
respon: .asciiz "\nThe factorial of the entered number is: "
nl: .asciiz"\n"
.text
fact:
beqz $a0,return1
li $v0, 1
li $t0, 1
fact_loop:
bgt $t0, $a0, end_fact_loop
mul $v0, $v0, $t0
addi $t0, $t0, 1
j fact_loop
end_fact_loop:
jr $ra
return1:
li $v0, 1
jr $ra
main:
li $v0, 4
la $a0, num
syscall
li $v0, 5
syscall
move $t0, $v0
li $v0, 4
la $a0, respon
syscall
li $v0, 1
move $a0, $t0
syscall
jal fact
move $t0, $v0
li $v0, 1
move $a0, $t0
syscall
li $v0, 4
la $a0, nl
syscall
################################
li $v0, 4
la $a0, num2
syscall
li $v0, 5
syscall
move $t0, $v0
li $v0, 4
la $a0, respon
syscall
li $v0, 1
move $a0, $t0
syscall
jal fact
move $t0,$v0
li $v0, 1
move $a0, $t0
syscall
li $v0, 10
syscall
To get rid of printing the input you have to remove the syscall you are issuing to print them.
That is, before jal-ing fact (both times) you are issuing these instructions:
li $v0, 1
move $a0, $t0
syscall
Just, remove the first and third instruction and keep the move as you use it on your fact routine:
move $a0, $t0
A few suggestions:
Add a comment to each functional chunk of code.
Use a single-step to debug so you can see what's happening where.
Simplify the code to a minimal failing example. If you have two chunks of code both exhibiting the same problem, remove one of them and focus on the first without distractions and noise from the second.
Prune unnecessary code. For example, the return1: block and beqz $a0,return1 are superfluous because the main factorial loop will exhibit the same behavior automatically -- you don't need to handle $a0 == 0 specially.
Having followed these tips, I wound up with the following program:
.data
num: .asciiz "\nPlease enter a number: "
num2: .asciiz "\nPlease give your second number : "
respon: .asciiz "\nThe factorial of the entered number is: "
nl: .asciiz "\n"
.text
fact:
li $v0, 1
li $t0, 1
fact_loop:
bgt $t0, $a0, end_fact_loop
mul $v0, $v0, $t0
addi $t0, $t0, 1
j fact_loop
end_fact_loop:
jr $ra
main:
# print prompt "Please enter a number: "
li $v0, 4
la $a0, num
syscall
# get user input for first fact call
li $v0, 5
syscall
move $t0, $v0
# call fact(n)
move $a0, $t0
jal fact
move $t0, $v0
# print "factorial is..."
li $v0, 4
la $a0, respon
syscall
# print the result of fact(n)
li $v0, 1
move $a0, $t0
syscall
# print newline
li $v0, 4
la $a0, nl
syscall
# exit program
li $v0, 10
syscall
The problem of double-printing is caused by this code:
li $v0, 1
move $a0, $t0
syscall
The move $a0, $t0 is necessary to set up the fact call, but we don't want li $v0, 1 and syscall, which prints the argument without a newline before the result of fact, causing your unwanted output.
A good technique to prevent this in the future is ensuring your argument set-up for the function call to fact happens right before the jal.
I'll leave it as an exercise to adapt this to your second chunk of code, which has the same extra syscall to service 1 (print integer).

How to store the input correctly in MIPS?

Although I have try to input different value ,but the Qtspim still print out the value"0" and the input is also not saved in the register ,I try to find the answer in internet,but it seem like no one have face this problem before.I do it work for 4hrs, I FEEL very frustrated with this.
here is my code ,I try to define whether the input is prime number or not.
# Power program
# ----------------------------------
# Data Segment
.data
request: .asciiz "Enter an integer:"
Yes: .asciiz " is a prime number.\n"
No: .asciiz " is not a prime number\n."
End: .asciiz"End!\n"
Key: .word -1
One: .word 1
# ----------------------------------
# Text/Code Segment
.text
.globl main
main:
lw $t1,One
add $s2,$zero,$zero
lw $s3,One
lw $s0,Key
add $s5,$zero,$zero
j power # call the function power
li $v0, 10 # call code for exit
syscall # system call
.end main
.globl power
power:
j power_loop
power_loop:
la $a0, request # load string request in memory to $a0
li $v0, 4 # print out the string
syscall #prevent Memory address out of bounds
li $v0, 5
syscall
move $s7,$v0
beq $s7, $s0, exit_L #when input =-1 exit
j Prime #otherwise go to define the input whether prime num
Prime:
beq $s7,$t1,result
div $s7,$t1
mthi $t4
beq $t4,$zero,count
addi $t1,$t1,1
j Prime
count: #counting the number of factors
addi $s2,1
addi $t1,$t1,1
result: addi $t1,$zero,1
bne $s2,$s3,resultNo
beq $s2,$s3,resultYes
resultYes: li $v0,1
move $a0,$s7
syscall
add $s2,$zero,$zero
la $a0,Yes
li $v0,4
syscall
j power_loop
resultNo: li $v0,1
move $a0,$s7
syscall
add $s2,$zero,$zero
la $a0,No
li $v0,4
syscall
j power_loop
exit_L:
la $a0,End
li $v0,4
syscall
jr $ra
.end power

MIPS: how can I apply the integer which users input into arithmetic function?

This is my first time coding PCSPIM. I find that there is a little trouble with my code.
.data
user_input: .asciiz "\n\nEnter an Integer for the value of n: "
result_display: .asciiz "\nThe sum from 0 to n is "
Greeting: .asciiz "\n\nThank you!"
.text
main:
#user input
li $v0, 4
la $a0, user_input
syscall
#allow user input
li $v0, 5
syscall
#store the input value into t8
move $t8, $v0
#calculation
addi $s0, $zero, $t8
I wish to use the integer value ($t8) that users input into the #calculation section, but it ends up with error.
addi $t0, $zero, 0
loop1:
add $t0, $t0, $s0
addi $s0, $s0, -1
bne $s0, $zero, loop1
nop
nop
# Display the result
li $v0, 4
la $a0, result_display
syscall
# Print out the result
li $v0, 1
move $a0, $t0
syscall
# Greets the user
li $v0, 4
la $a0, Greeting
syscall
# Exit the program
li $v0, 10
syscall
Sorry for my broken English.
The error is in the way you are using the "addi" instruction. The instruction requires an immediate (number) value to be passed as the third operand and not an architectural register. If you update the "addi" instruction to "addu" the code should work.

How to get the time taken for a calculation using MIPS assembly language?

So currently I want to calculate the time taken for a calculation. I am using 30 in $v0, but the problem is every time print the time taken, a huge number is shown which is not related. so how can I fix this problem?
any help is appreciated
An example code
.data
inputNumber: .asciiz "Input an integr: "
newLine: .asciiz "\n"
done1: .asciiz "loop completed\n"
.text
main:
#print inputNmber string
li $v0, 4
la $a0, inputNumber
syscall
#read integer
li $v0, 5
syscall
#move int to another register
move $t0, $v0
# get starting time
li $v0, 30
syscall
# store it in another place
move $a0, $v0
#while loop counter
addi $t1, $zero, 1
# while loop
while:
bgt $t1, $t0, done
#print inputNmber int
li $v0, 1
move $a0, $t0
syscall
#print new line
li $v0, 4
la $a0, newLine
syscall
addi $t1, $t1, 1
j while
#Exit the program
li $v0, 10
syscall
done:
# get finishing time
li $v0, 30
syscall
# store it in another place
move $a1, $v0
#printing done1
li $v0, 4
la $a0, done1
syscall
# Subtract time values
sub $t2, $a1, $a0
#print time taken
li $v0, 1
move $a0, $t2
syscall
# exit program
li $v0, 10
syscall
First of all, after returning from the syscall which gives you the system time, you store the result in $a0. However, inside the loop, you erase the value of $a0 :
#print inputNmber int
li $v0, 1
move $a0, $t0
Moreover, by looking at the syscall table, you can see that this syscall put the time value like this :
$a0 = low order 32 bits of system time
$a1 = high order 32 bits of system time
And not in $v0. So you should adapt your move instructions and your subtraction taking this in consideration
NOTE: If you are using an emulator, this sycall is NOT compatible with SPIM, only MARS
Source for syscalls: https://courses.missouristate.edu/KenVollmar/mars/Help/SyscallHelp.html

displaying the factorial of each value of the index of a loop does not work. MIPS

I am trying to display the factorial of the current value of the index of a loop in MIPS but, my loop does not work at all. It keeps freezing every time I run the code. Let say I have a for loop such that (i=1; i<=5; i++), for each value of i, I would like to display the current factorial(i). The number 5, is actually provided by the user, in other words, the number can change(1-10). I have tried to figure out why my loop causes the code to freeze, but I have no clues so far. Your help will be very appreciated. The code is bellow.
.data # data declaration section; specifies values to be stored
# in memory and labels whereby the values are accessed
Prompt: .asciiz "\nEnter the number to compute the factorial:\n"
message: .asciiz "\nResult of computation is:\n"
result: .word 0
#--------------------------------
# main function |
#--------------------------------
.text # Start of code section
.globl main
main: # Execution begins at label "main". The prompt is displayed.
li $v0, 4 # system call code for printing string = 4
la $a0, Prompt # load address of string to be printed into $a0
syscall # call operating system to perform operation;
# $v0 specifies the system function called;
# syscall takes $v0 (and opt arguments)
# Read integer N
li $v0, 5
syscall
move $t0, $v0 #copy integer N into $t0
li $t1, 1 #initialize i=1
loop:
blt $t0, $t1, exit_loop # if number<1, exit...
move $a0, $t0 # copy N into $ao
jal fact #else call fact
sw $v0, result
li $v0, 4 #Display message
la $a0, message
syscall
li $v0, 1 #print result
lw $a0, result
syscall
sub $t0, $t0, 1 #Decrement N by one, N--
j loop
exit_loop:
jr $ra #return address
exit: #exit the program
li $v0, 10
syscall
.globl fact
.ent fact
fact:
subu $sp, $sp, 8
sw $ra, ($sp)
sw $s0, 4($sp)
li $v0, 1 #check base case
beq $a0, 0, end_fact
move $s0, $a0 #fact(n-1)
sub $a0, $a0, 1
jal fact
mul $v0, $s0, $v0 #n*fact(n-1)
end_fact:
lw $ra ($sp)
lw $s0, 4($sp)
addu $sp,$sp, 8
jr $ra
#end of factorial function
Your problem is in the instruction at exit_loop label:
exit_loop:
jr $ra #return address
You are jumping again into the loop because you haven't saved $ra at the start of your main function and you are also not restoring it before issuing that jr
In fact, your code, as is, should just terminate (syscall 10) and not issue a jump because you are implementing the main function and not a function to be called from elsewhere.
So, i'd change that code to:
exit_loop:
li $v0, 10
syscall
Looking a bit more into your code, you already have that code (on label exit), so you might just remove your exit_loop code and branch to exit instead of exit_loop in the branch that goes just after loop label.