Mips program to Count No of occurrences for each character in paragraph - mips

How can I write a Program in Mips to Count No of occurrences for each character in paragraph?
I wrote the program in c language but Couldn't convert it to Mips.
this is the c code
#include<stdio.h>
int main() {
char para[100];
printf("Enter Paragraph : ");
scanf("%[^\n]s", para);
int length = strlen(para),i,j;
int freq[length]; //array of frequncy char
for(i = 0; i < strlen(para); i++) {
freq[i] = 1;
for(j = i+1; j < strlen(para); j++) {
if(para[i] == para[j]) {
freq[i]++;
para[j] = '0'; ////Set para[j] to 0 to avoid printing visited character
}
}
}
printf("Characters and their corresponding frequencies\n");
for(i = 0; i < length; i++) {
if(para[i] != ' ' && para[i] != '0')
printf("%c-%d\n", para[i], freq[i]);
}
return 0;
}

Not sure about the paragraph but i have a one for a string;
.data
string: .space 100
.text
main:
la $a0, string # input string
li $a1, 100 # maximum size of string
li $v0, 8 # represents reading string
syscall # call system
li $v0, 12 # 12 represents reading character
syscall # call system
move $s2, $v0 # $s2= character
li $s1, 100 # $s1= maximum size of string
li $t4, 0 # count (number of occurrances)
li $t0, 0 # i(index)
bge $t0, $s1, print # i>= string length, exit
loop:
lb $s0,($a0) # the first character of string into $s0
bne $s0, $s2, skip # skip increasing the counter if item does not equal
add $t4, $t4, 1 # otherwise increment the counter
skip:
addiu $a0, $a0, 1 # increment index
beq $s0,0,print # go to print label if $s0=0 so $s0 ='\0'
j loop # go back to loop
print: # print the result
#addi $v0, $t4, 0 # $v0= $v4= number of occurrences
li $v0,1 # 1 represents printing integer
move $a0,$t4 # $a0=$t4 = number of occurances of character
syscall # call system
# Terminate the program
li $v0, 10 # 10 represents exit
syscall # call system
The input/output isn't structured well in this, just write the sentence at first then enter and write the character you want to get the occurrence of.
Hope this could in any way help you

Related

MIPS Swap Function went into infinite loop

I am writing a MIPS move vowels function, now I am stuck in a infinite loop because something wrong with the return address. Can someone help here? The issue is only for function "moveVowelsToBeginning", functions countvowels and isVowels work fine.
C code:
char myName[8] = "example";
int main()
{
vowels=countvowels(0,6); //count the vowels using recursion
moveVowelsToBeginning(0,6); //move vowels to the beginning
return 0;
}
int countvowels(int low, int high)
{
omit...
}
int isVowel(int low) // whether the indexed character is a vowel
{
if vowel ("omit code here")
return 1;
else
return 0;
}
int moveVowelsToBeginning(int low, int high)
{
int i, j; //two indexes
char temp;
j=low; //this index used as head of detected vowels
for(i=low;i<=high;i++)
{
if(isVowel(i))
{
//swap characters
temp = myName[j];
myName[j]= myName[i];
myName[i] = temp;
j++;
}
}
}
MIPS code for function moveVowelsToBeginning:
moveVowelsToBeginning:
addiu $sp,$sp,-16 #stack grows by 16 bytes
sw $ra,12($sp) #save return address
sw $a0,0($sp) #save the arguments into stack
sw $s0,4($sp) #$s0 is used to hold the variable i
sw $s1,8($sp) #$s1 is used to hold the variable j
add $s0,$zero,$a0 #i==0
add $s1,$zero,$a0 #j==0
addiu $t3,$zero,6 #high==6
la $t7, myName #gets base address of myName
for_loop:
bgt $s0, $t3, for_loop_done #if i>high, go to for_loop_done to exit the loop
jal isVowel #jump to procedure isVowel
bne $v0, $zero, swap #compare the return value to 0, if not 0, call swap procedure.
addi $s0, $s0, 1 #i++
move $a0, $s0
j for_loop #loop again
swap:
addiu $sp,$sp,-8 #stack grows by 24 bytes
sw $ra,4($sp) #save return address
sw $s2,0($sp) #$s2 is used to hold the variable temp
add $t4,$t7,$s1 # myName[j] = myName + j
lbu $s2,0($t4) # temp=myName[j]
add $t5,$t7,$s0 # myName[i] = myName + i
lbu $t6,0($t5) # myName[i]
lbu $s7,0($t4) # myName[j]
move $s7,$t6 # myName[j]= myName[i]
move $t6,$s2 # myName[i] = temp
sb $s7,0($t4)
sb $t6,0($t5)
addi $s0,$s0,1 # i++
addi $s1,$s1,1 # j++
sw $s2,0($sp) #restore
sw $ra,4($sp)
addiu $sp,$sp,8
jr $ra
for_loop_done:
lw $s1,8($sp)
lw $s0,4($sp)
lw $a0,0($sp)
lw $ra,12($sp)
nop # put in breakpoint here to show memory

MIPS practice in writing lists of number

As the question required below,
Write a program in MIPS32 assembly language which reads a positive integer N and prints out the following:
1
12
123
1234
12345
...
1 2 3 4 5 6 ... N
Here is my code shown below:
.data
word: .asciiz "Please enter a random row: \n"
.text
.globl main
main:
la $a0, word # load word
li $v0, 4
syscall
li $v0, 1 # service 1 is print integer
move $a0, $t0 # move register to be printed into argument
register $a0
syscall
lw $s0, row # $s0 = row
addi $s0, $s0, -1 # for accommodating loop condition
li $s1, 1 # set i = 1
li $s2, 1 # set j = 1
loop1:
blt $s0, $s1, Exit # for(i = 0; i < row; i++)
addi $s1, $s1, 1 # i++
li $s2, 1 # resets j to 1 after every iteration of for
loop
move $a0, $t0 # move register to be printed into argument
register $a0
j loop2 # executing the nested for loop
loop2:
blt $s1, $s2, loop1 # for(i = 0; i < j; i++)
li $v0, 1 # read_double => scanf("%d")
move $a0, $t0 # move register to be printed into argument $a0
syscall
j loop2
li $v0, 10 # loading exit code
syscall # execute exit
As I tend to run it through, then I still could not achieve the expected outcome.
Here's how you'll write the code to do this:
Ask user for N value, & save.
Create a loop that will continue until N iterations (see conditional branching)
For N iterations, save the value 1, 1+=1, ... N in the register.
Remember that each word is 4 bytes. Make sure you are changing where you are accessing your register to save your values correctly, or else they will overwrite each other.
Use another loop to print all values (again, conditional branching).
If you want help with code, try writing some first. :-)

How to debug my Fibonacci generator in MIPS assembly language?

My code should accept a value n from the user to output the Fibonacci series. The code does not work from 4 and above. Also, how do I fix the code so that the fib series start from 0, not 1. The output of the code should be as follows if the user inputs 4
0 1 1 2
Here is the code
.data
string:.asciiz "Enter N: " # space to insert between numbers
space:.asciiz " " # space to insert between numbers
.text
la $a0, string
li $v0, 4
syscall # print the string
li $v0,5 #read inetger in $t0
syscall
move $t0,$zero
addi $t0,$v0,-1
move $t1,$zero
addi $t1,$t1,1
move $s0,$zero
addi $s0,$s0,1
move $a0,$s0
li $v0, 1 # $integer to print
syscall
la $a0, space
li $v0, 4
syscall # print the string
loop:
move $a0,$s0
li $v0, 1 # $integer to print
syscall
la $a0, space
li $v0, 4
syscall # print the string
addi $t0,$t0,-1
beq $t0,$zero,stop
add $s0,$s0,$t1
sub $t1,$a0,$t1
j loop
stop:
li $v0, 10 # system call for exit
syscall # Exit!
You've implemented the algorithm incorrectly. What you've written translates into something like this:
int prev1 = 1, fn = 1;
for (int n = 0; n < input; ++n) {
printf("%d ", fn);
fn += prev1;
prev1 = &space - prev1;
}
But what you should have done is more like:
int prev2 = 0, prev1 = 1;
for (int n = 0; n < input; ++n) {
int fn = prev1 + prev2;
printf("%d ", prev2);
prev2 = prev1;
prev1 = fn;
}
Regarding the question from your title ("How to debug?"): SPIM (and its variants) and MARS both give you a lot of debugging features.
There's the code, data, and register viewers. You can single-step through your code (typically using the F10, but it may differ between different simulators), and also set breakpoints at code locations of particular interest.

Move integer to new register without overwriting in MIPS

I'm very new to MIPS and this site (this is my first post) so please bear with me here...I have to take a user-entered number, reverse it integer by integer using division (HI/LO) and store the remainder into a new register, in order to compare the resulting reversed number against the original to see if it is a palindrome. That's fine, got that division part (I think?), but once I divide the second time and try to add the second remainder onto the remainder of the first division, it will simply overwrite the contents of the register, not add a number at the end of it, right? I can't find the answer to this on the internet. How can I accomplish this? Because simply doing 'move' will overwrite the contents, correct? Here's my code so far
li $v0, 4 # System call code for print string
la $a0, Prompt # Load address for Prompt into a0
syscall
li $v0, 5 # System call code for read integer
syscall # Read the integer into v0
move $t0, $v0 # Move the value into t0
move $t9, $t0
li $s0, 10 # Load 10 into s0 for division
li $s1, 0 # Load 0 into s1 for division
div $t0, $s0 # Divides t0 by 10
mfhi $t1 # Move remainder into t1
mflo $t0 # Move quotient into t0
Essentially, I want to concatenate the remainders together, not add them together or overwrite the register. Let's say the first remainder is 3, second is 6, third is 9. At the end of it, I don't want it to be 18, or 9. I want it to be 369.
Your div/mfhi/mflo were fine. What you needed was a loop that has a second variable.
I've created the equivalent C code and added it as a comment block and created a working program [please pardon the gratuitous style cleanup]:
# int
# rev(int inp)
# {
# int acc;
# int dig;
#
# acc = 0;
#
# while (inp != 0) {
# dig = inp % 10;
# inp /= 10;
#
# acc *= 10;
# acc += dig;
# }
#
# return acc;
# }
.data
Prompt: .asciiz "Enter number to reverse:\n"
nl: .asciiz "\n"
.text
.globl main
main:
li $v0,4 # System call code for print string
la $a0,Prompt # Load address for Prompt into a0
syscall
li $v0,5 # System call code for read integer
syscall # Read the integer into v0
bltz $v0,exit # continue until stop requested
move $t0,$v0 # Move the value into t0
li $t3,0 # initialize accumulator
li $s0,10 # Load 10 into s0 for division
li $s1,0 # Load 0 into s1 for division
next_digit:
beqz $t0,print # more to do? if no, fly
div $t0,$s0 # Divides t0 by 10
mfhi $t1 # Move remainder into t1 (i.e. dig)
mflo $t0 # Move quotient into t0 (i.e. inp)
mul $t3,$t3,$s0 # acc *= 10
add $t3,$t3,$t1 # acc += dig
j next_digit # try for more
print:
li $v0,1 # print integer syscall
move $a0,$t3 # get value to print
syscall
li $v0,4
la $a0,nl
syscall
j main
exit:
li $v0,10
syscall

Java to mips assembly exercise

I have an assignment where my goal is to translate the following Java code(in the comment block at the top of the asm file) into mips assembly code. When I try to compile in QTSpim I get and error saying "Attempt to execute non-instruction at 0x0040007c". Also I keep getting an error that says my main label was used for the second time on line 36 but I don't see how this is possible. Any help would be appreciated, thanks.
Here is my code:
########################################################################
# program description:
#Translate this into assembly:
#
#int w1 = 40; // use a register for this variable
#int w2 = 20; // use a register for this variable
#int total; // use a register for this variable
#int result[4]; // note: int = 1 word = 4 bytes
#
#total = w1;
#for (int i = 0; i < 4; i++) {
# total = total + w2;
# if (total > 100) {
# total = total - 100;
# }
# result[i] = total;
# System.out.println(total); // C++: cout << total << '\n';
#}
#return;
#
#
# Arguments: w1, w2, total.
#
#
#
#
########################################################################
.data
result: .word 4
.text
main:
li $s0, 40 #w1
li $s1, 20 #w2
li $s2, 0 #total
li $s3, 0 #loop counter
li $s4, 4 #loop conditional
li $s5, 100 #if conditional
add $s2, $s2, $s0
loop:
beq $s3, $s4, end #if the counter is greater than 4, exit loop
add $s2, $s2, $s1 #total = total + w2
bgt $s2, $s5, then #if total is greater than 100 branch to then
then:
sub $s2, $s2, $s5 #total = total - 100
sw $s2, result #store total into result
li $v0, 1 #print out total
move $a0, $s2
syscall
else:
sw $s2, result
li $v0, 1 #print out total
move $a0, $s2
syscall
end:
You need to explicitly exit your program once it has finished, otherwise the CPU will just continue executing whatever happens to be located in memory right after your program. When you use SPIM (or one of the other simulators derived from SPIM) you can use syscall 10 for this:
# syscall 10 == exit
li $v0,10
syscall