MIPS Assembly creating character checker - arrays

I am looking for help on how to take a string from the user and then output the number of times each letter was used in the string.
Pseudo code
string "Please enter a string:"
take string and save into an array,
check for ascii duplicates of character values and then output when corresponding letter is output.
example: Hello World
A:
B:
C:
D: 1
E: 1
...
H: 1
...
W: 1
code
.data
intro: .asciiz "Letter Checker Program"
question: .asciiz "\nPlease enter a string for evaluation: "
string: .space 1024
alphabet: .space 26
.text
main:
jal setup
#jal analyze
#jal results
li $v0, 10
syscall
setup:
li $v0, 4 # outputing name and program information
la $a0, intro
syscall
li $v0, 4 # asksing for string input
la $a0, question
syscall
li $v0, 8
la $a0, string
li $a1, 1024
syscall
jr $ra # return
analyze:
loop:
loop:
results:

What you want to do is:
Create some space (26 * 4 bytes) to store the results and fill with 0
Loop over every letter in the string and load with lb
Determine the numerical value of the letter, and thus the memory location (of step 1). Don't forget about lower and upper case letters.
Load that memory location (4 bytes, use lw), increase the value with 1, and store again with sw
Stop when you encounter 0 (not the letter '0')
In analyze, loop over every letter in the alphabet, load the corresponding memory location from step 1, and print results

Related

from java to MIPS assembly for a simple while loop [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 25 days ago.
Improve this question
i need to convert a code from java to assembly, but it only prints the first message. but the last two message dosent print neither the message nor the numbers of the result.
the two code in java and assembly are that i wrote as follow :
the code in java:
/**
* this program count how many 10s can be in a givin number the return the extra or the remain that less than 10
*/
Scanner input=new Scanner(System.in);
System.out.println("enter num: ");//print input message
int num=input.nextInt();// user input
int numOf10=0;//counter
while(num>9){ //start of while loop
num-=10;//subtruct 10 from the input number
numOf10++;//add one to the counter
}
System.out.println("number of 10 is: "+numOf10);//print message contain
System.out.println("the remain: "+num);//print message contain
////////////////////////////////////////////////////////////////////////////////////
the code in assembly:
.data
EnterMessage: .asciiz"Enter the number:\n "
ResultMessage: .asciiz"number of 10 is:\n"
remainMessage: .asciiz"the remain:\n "
.text
main:
#ask user to enter input
li $v0,4
la $a0,EnterMessage
syscall
#read user input
li $v0,5
syscall
#save input
move $t0,$v0
#creat variables
#$t2=9
addi $t2,$zero,9
#counter=$t3=0
addi $t3,$zero,0
#jal loop
#while loop
loop:
ble $t1,$t2,exit
subi $t0,$t0,10
addi $t3,$t3,1
j loop
print:
#print ResultMessage num
li $v0,1
move $a0,$t3
syscall
#print ResultMessage
li $v0,4
la $a0,ResultMessage
syscall
#print remainMessage num
li $v0,1
move $a0,$t0
syscall
#print remainMessage
li $v0,4
la $a0,remainMessage
syscall
#close the program
exit:
#end
li $v0,10
syscall
Your problem is here:
ble $t1,$t2,exit
There are a couple of problems here. First, exit leads to:
#close the program
exit:
#end
li $v0,10
syscall
So you've jumped to the end without doing anything.
Second, you've chosen $t1 as one of your registers for the compare, which you never set up. So its value is currently unknown (most likely the kernel or OS or whatever zeroed all your registers prior to main but it's not a good practice to assume that.)
Let's think about what's being asked:
while(num>9){ //start of while loop
num-=10;//subtruct 10 from the input number
numOf10++;//add one to the counter
}
When translating a high-level language to assembly we don't have to do everything the same way it was written in the source language. In terms of goto we can think of this as:
loop_begin:
if (num <= 9) goto loop_exit;
num -= 10;
numOf10++;
goto loop_begin;
loop_exit:
You've got the right idea for the most part. The nice thing about MIPS is that the branching syntax isn't nearly as obtuse as other assembly languages, since you don't have to remember whether carry clear means less than or greater than etc.
loop:
ble $t0,$t2,print # if $t0 (num) <= 9 goto print
subi $t0,$t0,10 # num = num - 10
addi $t3,$t3,1 # counter++
j loop # goto loop
Edit: Fixed typo in comments in last section

MIPS: Writing code to ask a user for an input and printing responses

I am really struggling with assembly language and, unfortunately, have gotten into the habit of treating it more like an assignment than a learning objective. I am now being tasked with writing some code that asks a user for an input (in this case, an integer) and then prints a response based on that integer.
Directions:
Ask a user for an integer-- if the integer is '8', print "Great!". If it's not 8, print "Try again" and then ask them to submit one more time. If they don't print the integer, '8', on the second attempt, simply type game over.
.data
message: .asciiz "Please enter an integer:"
correct_str: .asciiz "Great!\n"
incorrect_str: .asciiz "Game over! \n"
li $t0,8 #this is the correct answer
li $t1,0 # creates a counter of two attempts
loopcheck:
la $a0, message # prompt user
li $v0, 4
syscall
li $v0, 5
syscall
move $s1, $v0 # s1 becomes what user inputs
#this is where we check to see if it's 8, printing game over or looping again and printing game over if not correct on second time
printGameOver:
la $a0, wrong_str
li $v0, 4
syscall
j done
printright:
la $a0, right_str
li $v0, 4
syscall
done: #exit
li $v0, 10
syscall

Mips, continuous user input

How would I go about asking a user for continuous input? Basically I want to capture only numbers greater than 0, anything less than 0 I want to print an error message followed by the enter number message.
How would you go about solving this in high-level language pseudocode? One way is -
while true
print("Enter a number: ")
n = read_a_number()
if n < 0
print("Error. Negative number")
else
# process the non-negative number (>= 0)
# detect when to break while loop
Once the above is clear, it is fairly easy to translate this to MIPS.
.data
prompt: .asciiz "Enter a number: "
error: .asciiz "Error. Negative number\n"
.text
while:
la $a0, prompt # print prompt to enter a number
li $v0, 4 # $v0 = 4 to print string with address in $a0
syscall
li $v0, 5 # to read an int. Read in $v0
syscall
bltz $v0, negative # is the input negative?
j non_negative # else, handle non_negative
negative:
la $a0, error # print error
li $v0, 4
syscall
j next # and goto 'next'
non_negative:
# process the non-negative number (>= 0)
j next # and goto 'next'
next:
# detect when to break while loop (or do that at the start of the loop)
j while # continue loop
after_while: # after the loop
li $v0, 10 # $v0=10 to exit
syscall

Create an array of size n from user input n

For this assignment i need to be able to make an array of size n based on a user inputed value from zero to fifty. So far this is what ive done below. If you have any advice for the question overall that would be very helpful too.
a) Prompt the user for an integer in the range of 0 to 50. If the user inputs 0 the program stops.
b) Otherwise, the program stores the numbers from 0 up to the input value into an array of words in memory, i.e. initializes the array with values from 0 up to N where N is the value that user has inputted.
c) The program then adds the value of all items of the array together (up to N) by loading them from the main memory then add them up, then prints out the sum with the message "The sum of integers from 0 to N is:". For example, if the user gave 5 as the input the program prints out "The sum of integers from 0 to 5 is 15".
Submit your work as a zip file as specified in the syllabus to eLearning by the due date.
.data
userPrompt : .asciiz "enter in an integer from zero to fifty "
zeroMessage : .asciiz " you have entered a zero , the program will close "
incorrectEntry : .asciiz " you have entered in a value greater than 50 ,
this is an incorrect value"
InputVal : .word
upperLim : .word 50
Array : .space InputVal
.text
main:
addi $t7 , $zero , 50
li $v0, 4 # load for printing of strings
la $a0, userPrompt
syscall
# take in user input and move the read in number to a temp
li $v0, 5
la $t0 , InputVal
syscall
# Store int A into memory
move $t0 , $v0
beq $t0 , $0 , numbersEqual
la $t1 , upperLim
li $v0 , 1
move $a0 , $t1
syscall
slt $t3 ,$t0 , $t1
sw $t0 , InputVal
#beq $t3 , $0 , ELSE
ELSE :
li $v0 , 4
la $a0 , incorrectEntry
syscall
li $v0 , 10
syscall
numbersEqual:
li $v0 , 4
la $a0 , zeroMessage
syscall
li $v0 , 10
syscall
The assembly language is symbolic language for machine code, and machine code is what your CPU can execute.
After you run assembler to compile your source, you get machine code, which is sort of final. Then you execute that machine code.
The .word 0x12345678 is not instruction of CPU, but directive of your assembler, it tells it to reserve whole word of memory at that place of machine code, and store value of 0x12345678 there. I'm not sure what .word without value does, whether it will reserve at least one word, you should rather do InputVal: .word 0 to be sure.
In the final machine code there is no ".word", that's not CPU instruction, there will be just those 4 bytes with their respective values forming word value, at some address, which was known to the assembler as symbol InputVal (that's also not part of machine code any more in this textual form, any instruction using this memory address has only the proper address encoded in it as numeric value, and the executable binary may contain some sort of relocation table for OS to patch addresses properly after loading the machine code to target memory before execution).
Now this may sounds like stating the obvious, but it's important for you to understand the difference, what is available when the CPU is already executing your machine code, and what is available during compilation by assembler (code not running yet).
Array : .space InputVal will not work as you wish, because InputVal is symbol of memory address. So the directive .space will either reserve bazillion bytes (value of memory address of InputVal), or more likely the compilation will fail. What you want is content of memory at InputVal, but that's not known yet, because the code didn't run, user didn't enter anything, it's still just assembly step. So the value is not know, you may just as write Array: .space 0. But that will reserve no space.
Unless you want to delve into dynamic memory allocation, there's simple trick to resolve such situation, which will work in your particular case. If you will read the task, the N is valid only when inputted value is from 0 to 50 (anything else is user error and you can exit). So for maximum N=50 you will need array of 51 values, and you will never need more.
So you can avoid all the dynamic memory allocation (at runtime) by simply doing:
.align 4 # make sure the reserved space is word-aligned
Array: .space (51*4)
This will reserve 204 bytes (51 words) of memory in the data area for your machine code, with symbol Array pointing at the first byte of it.
Now you have memory reserved, and you can store values into it, and use it. If you would want during runtime to change your mind, and use 52 words of memory, you are out of luck with such code. Then you need either to code dynamic allocation, or increment the hard-sized fixed buffer during compilation time.
Also your code has always 51 words available in that Array, so it's up to your code to use only the inputted N+1 values out of them. If user enters N=5, then you should work only over 6 words (24 bytes), ignoring the remaining reserved words).
So each loop in your code will be like for (i = 0; i <= N; ++i) Array[i] = i;, where N is the value entered by user during runtime (store it to InputVal reserved memory, so you can access it whenever you need it), not known during compilation.

How do I get an INTEGER and turn that into an ARRAY of separate single digit integers in MIPS?

Okay so I have an issue. I want to get an integer and turn it into an array of single-digit integers in MIPS but I'm not sure how to go about that.
Can you guys help me? I know how to do this in every other language except this one...
Example:
I want to the integer 32325
to be an array where A[0] = 3, A[1] = 2, A[2] = 3, ...
Can you please help me? I've been stumped for a while!
This is what I have so far...
.data
prompt: .asciiz
msg: .asciiz
array: .space 24 #6 digit number
.text
li $v0, 4 #print out
la $a0, prompt1
syscall
li $v0, 5 #take in int
syscall
la $a0, array# Set address t0 to be the array
I have no idea about MIPS, but the algorithm is quite simple
Divide the number by 10, as long as it is != 0 ... the reminders (in reverse order) are the digits. easiest way to store them would be the stack, since pop'ing them will bring them into correct order again:
counter=0
while (number !=0) {
push number%10
number /= 10
counter++
}
while (counter>0) {
pop number
store/display it
counter--
}

Resources