convert C factorial code to MIPS factorial - mips

I'm having trouble with converting the following C code to MIPS
#include <stdio.h>
int main (void)
{
int n = 0;
printf ("n = ");
scanf ("%d", &n);
int fac = 1;
for (int i = 1; i <= n; i++)
fac *= i;
printf ("n! = %d\n", fac);
return 0;
}
My code is not printing out the expected result, but it could successfully print "n:" etc.
### Global data
.data
msg1:
.asciiz "n: "
msg2:
.asciiz "n! = "
eol:
.asciiz "\n"
### main() function
.data
.align 2
.word 4
.text
main:
la $a0, msg1
li $v0, 4 #printf("n: ")
syscall
li $v0, 5 #scanf("%d", &n)
syscall
li $t0, 1
li $t1, 1
mul $t1, $t1, $t0 #t1 = t1*t0
add $t0, $t0, 1 #t0 = t0+1
la $a0, msg2
li $v0, 4 #printf("n!= ")
syscall
li $v0, 1 #print %d
la $a0, eol
li $v0, 4 #printf("\n")
syscall
li $v0, 0
jr $ra #return from main
My code does not produce any output, so I guess something may have went wrong in my loop

You are doing the loop section of the code that correwpods to the for loop in the c code, and you are not setting the value and calling syscall for the printf("%d") code.
### Global data
.data
msg1:
.asciiz "n: "
msg2:
.asciiz "n! = "
eol:
.asciiz "\n"
### main() function
.data
.align 2
.word 4
.text
main:
la $a0, msg1
li $v0, 4 #printf("n: ")
syscall
li $v0, 5 #scanf("%d", &n)
syscall
move $t2, $v0 # n = t2
li $t0, 1 # i = 1
li $t1, 1 # fact = 1
loop:
bgt $t0, $t2, end_loop # i > b - stop looping
mul $t1, $t1, $t0 #t1 = t1*t0
add $t0, $t0, 1 #t0 = t0+1
j loop
end_loop:
la $a0, msg2
li $v0, 4 #printf("n!= ")
syscall
li $v0, 1 #print %d
move $a0, $t1
syscall
la $a0, eol
li $v0, 4 #printf("\n")
syscall
li $v0, 0
jr $ra #return from main

Related

Getting Memory out of bounds exception while running code in QTSPIM

I am trying an array to save i * j values and print the values from array.
I have two loops loop1, loop2, where loop1 takes i and loop2 takes on j.
I am trying to save the i * j in a myarray which is space datatype.
I am getting exception Memory address out of bounds and unable to find whats the error.
.data
myarray: .space 10000
n: .word 1
space_line: .asciiz " "
new_line: .asciiz "\n"
.text
.globl main
main:
lw $a0, n
la $a1, myarray
li $a2, -1 #row
li $t0, 0
li $t2, 0
loop1:
addi $a2, $a2,1
bge $a2, $a0, print_loop
li $a3, 0 #column
j loop2
loop2:
bge $a3, $a0, loop1
#multiply a2 and a3
mul $t1, $a2, $a3
sw $t1, 0($a1)
addu $a1, $a1,4
addi $a3, $a3,1
j loop2
print_loop:
mul $t3, $a0, $a0
bge $t0, $t3, exit
li $v0, 4
lw $a0, myarray($t2)
syscall
li $v0, 4
lw $a0, space_line
syscall
rem $t4, $t3, $a0
beqz $t4, newline
addu $t2, $t2, 4
addi $t0, $t0, 1
j print_loop
newline:
li $v0, 4
lw $a0, myarray($t2)
syscall
exit:
# Done, terminate program.
li $v0, 10
syscall # all done!
.end main
For n =4,i am expecting the output in console as
0 0 0 0
0 1 2 3
0 2 4 6
0 4 8 12
You can find this problem by single stepping in the debugger.  Start with the smallest possible input, like n=1 as you're showing.  After each instruction, verify that it did what you want, and that it didn't do anything else except what you wanted.
Here's a hint: Pay attention to the difference between la and lw.  Also, If you want to put syscalls in the middle of your code or loops, then avoid the $a0 and $v0 registers for your own variables — just makes things easier/better.

How to count the number of spaces in MIPS?

I need to write a program in which the output will be the number of sentences and average number of words. The code is working perfectly for counting the sentences, but for the second task, it doesn't work. I'm using branch if equal with the current char and the register in which I've declared the ascii value for space which is 32. With this code, the output for the average words is the total number of characters from the whole input. I can't understand how it can count every character when the beq is clearly incorrect. (I've also tried with emptySpace: .asciiz " ", but it's not working)
This is what I got so far:
.data
str_input: .space 256
dot: .asciiz "."
msg1: .asciiz "Number of sentences: "
msg2: .asciiz "\nAverage number of words: "
.text
li $v0, 8 #read string
la $a0, str_input #address of str_input vo $a0
li $a1, 256 #256 max
la $a2, dot
lb $a2, 0($a2)
li $a3, 32
syscall
addi $t4, $zero, 0 #counter for words
addi $t5, $zero, 0 #counter for sentences
or $t0, $a0, $zero #$t0 pointer to array
start:
lb $t1, 0($t0) #$t1 current char
beqz $t1, end
jal check
addiu $t0, $t0, 1
j start
chech:
beq $t1, $a2, IsDot
beq $t1, $a3, IsEmptySpace
IsDot:
addi $t5, $t5, 1
jr $ra
IsEmptySpace:
addi $t4, $t4, 1
jr $ra
end:
la $a0, msg1 #address of msg1 in $a0
li $v0, 4 #load string in $v0
syscall
add $a0, $t5, $zero
li $v0, 1
syscall #print number of sentences
addi $t4, $t4, 1 #add the last word
div $t4, $t5 #divide number of words with number of sentences
mflo $t6
la $a0, msg2 #address of msg2
li $v0, 4 #load string in $v0
syscall
add $a0, $t6, $zero
li $v0, 1
syscall

Replacing repeated consecutive characters with X

I have some trouble with my code.
I need this in/output on the console.
Input String : aaabcccdeefggg
Input char: X
Replace:XXXbXXXdXXfXXX <--I want this output
But i get this output-->XXabXXcdXefXXg
I dont know where the bug is, i am searching for hours for this bug.
.data
enterString: .asciiz "Input String > "
enterChar: .asciiz "Input char> "
changedString: .asciiz "\nReplace: "
numberOfAdditions: .asciiz "\Total Replaces: "
userInput: .space 555
.text
main:
li $v0, 4
la $a0, enterString
syscall
li $v0, 8
la $a0, userInput
li $a1, 554
syscall
li $v0,4
la $a0,enterChar
syscall
li $v0,12
syscall
move $t5,$v0 # $t0 = character to be replaced
li $t0, 0
li $t1, 1
j findDoubleCharacters
findDoubleCharacters:
lbu $s0, userInput( $t0 )
lbu $s1, userInput( $t1 )
addi $t0, $t0, 1
addi $t1, $t1, 1
beq $s0, $s1, found
beq $s1, 0, end
j findDoubleCharacters
found:
subi $t0, $t0, 1
subi $t1, $t1, 1
sb $t5, userInput($t0)
addi $s2, $s2, 1
j findDoubleCharacters
end:
li $v0, 4
la $a0, changedString
syscall
li $v0, 4
la $a0, userInput
syscall
li $v0, 4
la $a0, numberOfAdditions
syscall
li $v0, 1
move $a0, $s2
syscall
...

how do I implement a jump address table in MIPS64? [duplicate]

C++ Program
# include < iostream >
# include <string >
using namespace std;
int main ()
{
int resistance ; // in Ohms
string partNum ; // Part Number
cout << " Enter resistance : " << endl ;
cin >> resistance ;
switch ( resistance )
{
case 3 : partNum = " OD30GJE "; break ;
case 10 : partNum = " OD100JE "; break ;
case 22 : partNum = " OD220JE "; break ;
default : partNum = "No match "; break ;
}
cout << " Part number : " << partNum << endl ;
return 0;
}
Translate the C code to MIPS assembly code, add to your code the capability to match the closest resistor. Be sure to use the jr instruction for the switch statement. Have your code get the resistance as input from the user and display to the console the resistor's corresponding or closest part number.
Mips Assembly Code
.data
int_value: .space 20
.align 2
input: .asciiz "Enter resistance.\n" # declaration for string variable,
string1: .asciiz "OD30GJE\n" # declaration for string variable,
string2: .asciiz "OD100JE\n"
string3: .asciiz "OD220JE\n"
string11: .asciiz "No Match\n"
string12: .asciiz "Enter resistance\n"
.text
main:
li $v0, 4
la $a0, input # print for input
syscall
la $t0, int_value
li $v0, 5 # load appropriate system call code into register $v0;
syscall # call operating system to perform operation
sw $v0, int_value # value read from keyboard returned in register $v0;
# store this in desired location
lw $s1, 0($t0)
condition1:
slt $t1, $s1, $zero # if $s1 < 0 $t1 = 1 else $t1 = 0
beq $t1, $zero, condition2 # if $t1 = 0; InvalidEntry
bne $t1, $zero, invalid_entry
condition2:
sgt $t1, $s1, -1 # if $s1 > -1 then $t1 = 1 else $t1 = 0
beq $t1, $zero, invalid_entry # if $t1 = 0; InvalidEntry
sgt $t1, $s1, 9 # if s1 > 9 t1 = 1 else $t1 = 0
bne $t1, $zero, condition3 # if $t1 does not equal = 0; condition3
li $v0, 4
la $a0, string1
syscall
j exit
condition3:
sgt $t1, $s1, 9 # if $s1 > 9 then $t1 = 1 else $t1 = 0
beq $t1, $zero, invalid_entry # if $t1 = 0; InvalidEntry
sgt $t1, $s1, 21 # if s1 > 21 t1 = 1 else $t1 = 0
bne $t1, $zero, condition3 # if $t1 does not equal = 0; condition3
li $v0, 4
la $a0, string2
syscall
j exit
invalid_entry:
li $v0, 4
la $a0, string11
syscall
j exit
exit:
li $v0, 10 # v0<- (exit)
syscall
The following shows how to make a jump table. The offset within the jump table is assumed to be in $s1. $s1 must be a multiple of 4 (i.e. a byte offset).
This code has not been tested!
. . . .
b 1f # jump past the jump table
nop # branch delay slot
# table of jump addresses
JTAB: .word LABEL1
.word LABEL2
.word LABEL3
1: la $t0, JTAB # load start address of the jump table
add $t0, $t0, $s1 # add offset to table address
lw $t1, 0($t0) # load the address stored at JTAB + $s1
jr $t1 # and jump to that address
nop # branch delay slot
LABEL1: # do something
b 2f # break
nop
LABEL2: # do something else
b 2f # break
nop
LABEL3: # do a different thing
b 2f # break
nop
2: # after the end of the "case statement"

function in mips that calculates the absolute value [duplicate]

This question already has answers here:
Integer absolute value in MIPS?
(5 answers)
Closed 2 years ago.
hello i have an exercise in mips that must call a function to calculates the absolute value of a number
i have write 2 codes but if you have any other solution write it
.data
message:.asciiz "give number: "
.text
main:
li $v0, 4
la $a0, message
syscall
li $v0, 5
syscall
add $t1, $v0, $zero
jal absolute
add $v0,$t2,$zero
li $v0, 1
syscall
li $v0, 10
syscall
absolute: ori $t2,$t1,0 #copy r1 into r2
slt $t3,$t1, $zero #is value < 0 ?
beq $t3,$zero,gg #if r1 is positive, skip next inst
sub $t2,$zero, $t0 #r2 = 0 - r1
jr $ra
gg:
#t2
and the second code is this
.data
question: .asciiz "give number"
.text
main:
li $v0, 4
la $a0, question
syscall
li $v0, 5
syscall
jal absolute
li $v0, 1
syscall
li $v1, 1
syscall
li $v0, 10
syscall
absolute:
slti $t0,$a0,0
bne $t0,$zero,g1
add $v0,$a0,$zero
jr $ra
g1:
sub $t2,$a0,$a0
sub $v1,$t2,$a0
j absolute
Try this:
.data
message: .asciiz "Enter the number: "
.text
.globl main
main:
# print message
li $v0, 4
la $a0, message
syscall
# read integer
li $v0, 5
syscall
slt $t0, $v0, $0 # $t0 = ( $v0 < 0 ? 1 : 0 )
bne $t0, $0, NEGATIVE # if($t0 != 0) goto NEGATIVE
j POSITIVE # goto POSITIVE (and dose nothing)
NEGATIVE:
# ~$v0 + 1
nor $v0, $v0, $0 # NOR with zero = NOT
addi $v0, $v0, 1 # $v0 =+ 1
POSITIVE:
# print $v0
move $a0, $v0
li $v0, 1
syscall
# print new line '\n'
li $v0, 11
addi $a0, $0, 10
syscall
jr $ra
Test:
Enter the number: 10
10
Enter the number: -5
5