MIPS : Printing n time a number in a file - mips

I'm currently working on a project for school. I'm asked to generate a random list of number in a text file, and first of all I tried to print n times a number in a test file, 31 for example. However, no matter the value of n, I always get my test.txt file with "31 " printed in but only one time. Here's my code (I'm a beginner btw) :
.data
question: .asciiz "\nEnter a number : ?\n"
mynumber: .asciiz "31 "
file: .asciiz "test.txt"
.text
.globl __start
__start:
li $v0, 4
la $a0, question
syscall
li $v0, 5
syscall
move $t0 $v0
li $t1 0
Loop:
blt $t0 $t1 exit
addi $t1 $t1 1
jal open_file
jal fill_file
jal close_file
j Loop
open_file:
li $v0, 13
la $a0, file
li $a1, 1
li $a2, 0
syscall
jr $ra
fill_file:
move $a0, $v0
li $v0, 15
la $a1, mynumber
li $a2, 3
syscall
jr $ra
close_file:
li $v0, 16
syscall
jr $ra
exit:
li $v0, 10
Does somebody have a solution for my problem? Would appreciate ! (Sorry for my english, not a native speaker)

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).

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.

MIPS multiplication using addition

sorry, I try to multiply two integers but it doesn't work. I can't find where the problem is.Maybe because of register' names but I don't know how to correct it. I correct many times but it is not successful. Could anyone give me some points?
.data
prompt1: .asciiz "Please enter the first signed (decimal) integer: "
prompt2: .asciiz "Please enter the second signed (decimal) integer: "
result_msg: .asciiz "The result of these two 16-bit integers\' multiplication is: "
.text
.globl main
main:
li $v0, 4 #print prompt
la $a0, prompt1
syscall
li $v0, 5 #read multiplicand
syscall
move $s0, $v0
li $v0, 4 #print prompt
la $a0, prompt2
syscall
li $v0, 5 #read multiplier
syscall
move $s1, $v0
Mult: ori $t0,$zero,1 #mask
move $s3, $0 #initialize the result register
move $t1, $0
loop: beq $s1, $zero, end #if the multiplier is 0 then finished
and $t1, $t0, $s1 #mask
beq $t1, 1, mult_add
beq $t1, 0, shift
mult_add: addu $s3, $s3, $s0 #add to get product
shift:
sll $s0, $s0, 1 #shift multiplicand left
srl $s1, $s1, 1 #shift multiplier right
j loop
end:
jr $ra
result: #input the print_string
li $v0, 4
la $a0, result_msg
syscall
exit:
li $v0, 1 #input result
move $a0, $s3
syscall
li $v0, 10 #exit
syscall
Inspecting your code I see that you jump to label end when you are done multiplying.
The instruction at that label issues a jr $ra which "returns from a function", but I guess you just want to print the result and exit.
Therefore I'd suggest you remove that instruction so as to print the result and exit and maybe remove label result as it is not used anywhere in your code.

Sum of two numbers in MIPS

I'm trying to practice my coding skill in MIPS (this is my first time ever learning an assembly language). I wrote this code below to sum up two user's inputs, and it is correct. However, the code is quite long..so, is there any way to optimize this code so it will be shorter? i need some suggestions. Thanks
.data
n1: .asciiz "enter your first number: "
n2: .asciiz "enter your second number: "
result: .asciiz "result is "
.text
#getting first input.
la $a0, n1
li $v0, 4
syscall
li $v0, 5
syscall
move $t0, $v0
#getting second input.
la $a0, n2
li $v0, 4
syscall
li $v0, 5
syscall
move $t1, $v0
#calculate and print out the result.
la $a0, result
li $v0, 4
syscall
add $t3, $t0, $t1
move $a0, $t3
li $v0, 1
syscall
#end program.
li $v0, 10
syscall
I also have wrote a program to calculate a factorial number. There are better ways to do this?
.data
str: .asciiz "Enter a number: "
result: .asciiz "The result is: "
.text
la $a0, str
li $v0, 4
syscall
li $v0, 5
syscall
move $s0, $v0 # move N into s0
li $s2, 1 # c = 1
li $s1, 1 # fact = 1
LOOP:
blt $s0, $s2, PRINT # if (n < c ) print the result
mul $s1, $s1, $s2 # fact = fact * c
add $s2, $s2, 1 # c = c + 1
j LOOP
PRINT:
la $a0, result
li $v0, 4
syscall
add $a0, $s1, $zero
li $v0, 1
syscall
li $v0, 10
syscall
The programs look ok, except for the use of the temporary registers $t0,...,$t9. These registers are not guaranteed to be preserved when another function is called, or when a syscall is issued. The $s0,...,$s7 registers are preserved across calls.
You need to replace: move $t0, $v0 with move $s0, $v0; move $t1, $v0 with move $s1, $v0 and add $t3, $t0, $t1 with add $s3, $s0, $s1.

What does the following QtSPIM/MIPS code do

What does the following QtSPIM/MIPS code do. Describe by referring to the functions of various blocks of the code (Block1, Block2, …).
Answer the questions in front of certain instructions.
Block1:
.text
main:
li $s4, 0
la $a0, input
li $v0, 4
syscall
li $v0, 5
syscall
move $t0, $v0 #Why do we need this?
Block2:
la $a0, output
li $v0, 4
syscall
move $a0, $t0
li $v0, 1
syscall
la $a0, newline # How will the output change if newline is replaced by newspace defined as “ “?
li $v0, 4
syscall
Block3:
Do:
move $a0, $s4
li $v0, 1
syscall
la $a0, newline
li $v0, 4
syscall
slt $s1, $s4, $t0
addi $s4, $s4, 1
bgt $s1, $zero, Do # Why can’t we use “beq $s1, 1, Do “?
Block4:
Exit:
li $v0, 10
syscall
.data
input: .asciiz "Input a number: "
output: .asciiz "Let me count till "
newline: .asciiz "\n "
So I need help with identifying what the code does... I have the concept I just want o make sure Im properly figuring this out... So I have this so far:
move $t0, $v0 #Why do we need this? --- to store number in t0
la $a0, newline # How will the output change if newline is replaced by newspace defined as “ “?
--- load address of string to be printed into $a0 and adds the space if replaced by newspace
the last one I cant quite figure out...