How can I load multiple saved value registers to argument registers to be used in a function? - parameter-passing

I am trying to take user input of three integers and pass them to a function, fme, which should return x^k mod n. When attempting to load the input from save registers to argument registers in order to run the function I get the error:
spim: (parser) syntax error on line 38 of file C:/Users/tamar/OneDrive/Documents/MIPS Projects/project2.s
lw $a0, $s0
Any suggestions for how I can execute this are appreciated. Here is my main.
main:
li $v0, 4
la $a0, out_string_x
syscall #print string (X)
li $v0, 5
syscall
move $s0, $v0 #take user input
li $v0, 4
la $a0, out_string_x
syscall #print string (K)
li $v0, 5
syscall
move $s1, $v0 #take user input
li $v0, 4
la $a0, out_string_x
syscall #print string (N)
li $v0, 5
syscall
move $s2, $v0 #take user input
#call fme function
lw $a0, $s0
lw $a1, $s1
lw $a2, $s2
jal fme
sw $v0, answer
#Display result
li $v0, 4
la $a0, result_message
syscall
li $v0, 1
lw $a0, answer
syscall
#end program
li $v0, 10
syscall

Related

MIPS32, Using the Stack for recursive multiplication, there is no output

So my test case is 7 for the multiplicand and 9 for the multiplier, I am trying to use Recursive Multiplication by using repeated addition, recursively. I'm a beginner in stacks in regards to MIPS so what could be the reason why nothing is wanting to output?
I am required to use $a0 -> Multiplicand, $a1 -> Multiplier, and $v0 -> Product
.text
main:
#Printing out prompt1
li $v0, 4
la $a0, prompt1
syscall
#Getting user input -> Multiplicand
li $v0, 5
syscall
move $a0, $v0
#Printing out prompt2
li $v0, 4
la $a0, prompt2
syscall
#Getting user input -> Multiplier
li $v0, 5
syscall
move $a1, $v0
#Loop
mult:
addiu $sp,$sp, -8
sw $a0, 4($sp)
sw $ra, 0($sp)
bne $a0, 1, else
add $v0, $v0, 0
j exit
else:
sub $a1, $a1, 1
jal mult
exit:
lw $a0, 4($sp)
add $v0, $v0, $a0
sw $v0, 4($sp)
addiu $sp, $sp, 8
jr $ra
lw $v0, multiplicand
li $v0, 1
la $a0, multiplicand
syscall
#Ending Program
li $v0, 10
syscall
.data
prompt1: .asciiz "Enter the multiplicand: "
prompt2: .asciiz "Enter the multiplier: "
multiplicand: .space 101

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.

Masking an integer in MIPS (quick and easy)

I want to input an integer and have it be expressed in both binary and hex. Then I want to move bits 12, 13, 14, and 15 to the least significant bits of $a0, and have the output be expressed as a binary and hex. Here's my program:
.data
enter: .asciiz "Please enter your integer:\n"
binaryI: .asciiz "\nHere is the input in binary: "
hexI: .asciiz "\n\nHere is the input in hexadecimal: "
binaryO: .asciiz "\n\nHere is the output in binary: "
hexO: .asciiz "\n\nHere is the output in hexadecimal: "
.text
prompt:
li $v0, 4
la $a0, enter
syscall
li $v0, 5
syscall
add $s2, $0, $v0
li $v0, 4
la $a0, binaryI
syscall
li $v0, 35
move $a0, $s2
syscall
li $v0, 4
la $a0, hexI
syscall
li $v0, 34
move $a0, $s2
syscall
addi $t0, $0, 7
srl $s0, $s2, 12
and $s0, $s0, $t0
li $v0, 4
la $a0, hexO
syscall
li $v0, 35
move $a0, $s0
syscall
li $v0, 4
la $a0, binaryO
syscall
li $v0, 34
move $a0, $s0
syscall
li $v0, 1
add $a0, $0, $s0
syscall
li $v0, 10
syscall
For the integer 1006460, for example, the inputs and hex output work perfectly, but the binary output has an extra 5 at the end. The error I get is this:
Here is the output in binary: 0x000000055
What may have caused this extra 5 to be at the end of the output?
How silly of me. I should have deleted
li $v0, 1
add $a0, $0, $s0
syscall
from my code.

MIPS: Printing Out a Histogram

I'm writing a MIPS program (assembly language) that takes in 10 integers and prints out a histogram represented by asterisks.
E.g.:
User input of 1, 2, 3, 4
Output:
*
**
***
****
I have most of this code written already in MIPS. The problem I am running into is printing out the correct length of asterisks. As of now it is simply printing out the a histogram all of the same length; the FIRST user inputed integer.
# program functionality:
.data
menu: .asciiz "\n1. New Histogram\n2. Print Histogram\n3. Quit\n"
prompt: .asciiz "\nEnter 10 numbers between 0 and 50 (inclusive):\n"
prompt1: .asciiz "\nEnter a valid number:\n"
asterisk: .asciiz "*"
space: .asciiz "\n"
array: .word 0:10
.text
main:
do:
jal print_menu
li $v0, 5
syscall
beq $v0, 1, new
beq $v0, 2, print
beq $v0, 3, quit
j do # end do
new:
jal new_user
j do
print:
jal print_user
j do
j quit
print_menu:
la $a0, menu
li $v0, 4
syscall
jr $ra
new_user:
la $a0, prompt
li $v0, 4
syscall
enter_loop:
la $t0, array
li $t1, 10
enter_loop_2:
la $a0, prompt1
li $v0, 4
syscall
li $v0, 5
syscall
sw $v0, ($t0)
addi $t1, $t1, -1
beqz $t1, end_loop_2
addi $t0, $t0, 4
j enter_loop_2
end_loop_2:
jr $ra
print_user:
la $t0, array
li $t1, 10
pLoop:
la $a0, space
li $v0, 4
syscall
asterisk_fun:
li $v0, 1
lw $a0, ($t0)
syscall
counter:
la $a0, asterisk
li $v0, 4
syscall
addi $a0, $a0, -1
beqz $a0, asterisk_end
j counter
asterisk_end:
jr $ra
addi $t1, $t1, -1
beqz $t1, endpLoop
addi $t0, $t0, 4
j pLoop
endpLoop:
jr $ra
quit:
li $v0, 10
syscall
The problems is that you are overwriting register $a0 in counter with the address of the asterisk, and you also used $a0 to count the number of items in that bucket.
Easy solution is to use other register (e.g. $a1) to count the number of items:
That would be:
#... your code
asterisk_fun:
li $v0, 1
lw $a1, ($t0) # Load number in $a1
move $a0, $a1 # move to $a0 just to print it
syscall
la $a0, asterisk
counter:
li $v0, 4
syscall
addi $a1, $a1, -1 # we use $a1 to keep the counter
beqz $a1, asterisk_end
j counter
asterisk_end:
# ... more of your code