Print partial string in MIPS - mips

I would like to print out "HEL" from the string "HELLO!". I am aware that I can load individual byte using lb in MIPS, however, how do I load the first 3 characters?
.data
string: .asciiz "HELLO!"
.text
lw $t6, string
lb $a0, 0-2($t6) # pseudo-code, returns "HEL"
li $v0, 4 # as opposed to 11, printing character
syscall

This has little to do with MIPS, and everything to do with C style nul-terminated strings, if you consider printing a character and whole string are your only options.
So, you can print the first 3 characters one a a time using syscall #11, or, copy them to another string and print it using syscall #4.
Otherwise, you can modify the string in place by smashing the 2nd L with a nul character, and print it.

Related

How to write a program that applies run length encoding compression to a given string using MIPS

Dynamic memory allocation and strings
Write a program that applies run length encoding compression to a given string. Follow the below steps:
Dynamically allocate memory from heap for two strings (an input string and an output string).
Read an input string (a-z, A-Z) of size less than 40 characters in this dynamic memory.
Iterate over the string looking for consecutive occurrences of the same character and replace
them with the character and a count.
Example, if the input string is AAAAAA, the output string should be A6. If you see
BBCCCCCCCCCCCCC, the output should be B2C13.
Note that the number 13 is represented as two separate characters ‘1’ and ‘3’ in the output string.
Single character occurrences do not need a count.
The output string should also be stored in the dynamic memory before it is displayed on the
console.
Implement a loop back to the main function. See the prompts below:
“Enter a string:”
“Compressed string is:”
“Do you want to apply run length encoding again?”
Test the program using the following data:
a. Input: AAAAaaabbcde Compressed string: A4a3b2cde
b. Input: XXXXXXXXXXYYZZZWERTT Compressed string: X10Y2Z3WERT2
.data
Prompt1: .asciiz "\n Enter a string."
.text
main:
li $v0, 4
la $a0, Prompt1
syscall
li $v0, 9
li $a0, 80
syscall
move $s0, $v0
li $v0, 8
la $a0, 0($s0)
li $a1, 40
syscall
move $t0, $a0
li $t4, 0
Loop:
lb $t1, 0($t0)
sb $t1, 40($s0)
addi $t0, $t0, 1
addi $t4, $t4, 1
addi $s0, $s0, 1
beq $t1, 0, End
j Loop
End:
neg $t4, $t4
add $s0, $s0, $t4
li $v0, 4
la $a0, 40($s0)
syscall
Generally, the algorithm should look something like this:
Get the pointers to your input string and your output buffer.
Loop:
Read the nth letter.
If it's the null terminator, exit.
Read the (n+1) th letter. If it's the null terminator, GOTO 5. If it's the same as the nth letter, GOTO 6.
Otherwise, add 1 to your index into the input string and GOTO 2.
Compress:
Create a counter variable for how many times you've seen the same letter in a row. It should start at two since you've seen two letters that are the same.
Add 2 to your index.
Compress_Loop:
Read the nth letter (remember, we added 2 to n in step 6.)
If it's not the same letter we've saw in Step 4, GOTO 11. Otherwise, continue.
Add 1 to your index into the input string, and add 1 to the counter variable, then GOTO 8.
Store the letter we saw in Step 4 into the output string.
Convert the counter variable to a string, and store it in the output string.
Adjust your index into the output string past what you just wrote.
GOTO 2.

MIPS string control not work fine

Hello everybody friends :) I coding an exercise but I have found a problem and in two days I haven't found the solution... I explain better, this is my code:
main:
#first message
la $a0, m1
li $v0, 4
syscall
#space in the stack
addi $sp, $sp, -41
#read the input
move $a0, $sp
li $v0,8
li $a1, 41
syscall
#bge $a0, 41, error
...
My code, read 40 characters (41 with string terminator)to count the vocal letters inside a string and, if I insert 41 characters send me an error message and repeat the stamp of the menu and the relative input, where is the problem? If I use this code without the control --> bge $a0, 41, error --> everything works fine, I can insert 1-40 characters with and without a space, when I insert this control give me the error that I have set when the string is 40+ character (see below to understand better)
Example with control:
input: hello(click return) ERROR: the string is bigger then 40 character
input: h ello(click return) ERROR: the string is bigger then 40 character
Any help or advice is the welcome :)
Thank you all, have a nice day!
P.s.
Sorry for my bad english
bge $a0, 41, error makes no sense here. System call 8 doesn't return a result, it just stores the characters into the buffer you supplied it with. If you want to find out the number of characters that were written to the buffer, loop over the buffer until you find a byte with the value 0 (or possibly 13 [carriage return]).
Friend maybe I have solved my problem... this is my solution I hope that it is good
#Create two copies of the string, one for nectCh and another for contaVocali
move $t0, $a0
move $t2, $a0
nextCh:
# extract a character from the string
lb $t1, ($a0)
# check the end of the string, so if it is more than 40+1
# give me the error message and repeat the prompt and the input
beq $t1, $zero, error
#check the carriage return and go to the function
beq $t1, 10, contaVocali
#next character
addi $a0, $a0, 1
# repeat
j nextCh
Is acceptable like solution?
Thank you
P.s.
The output is accordant with the output proposed on the exercise ;)

End character of user input string

I am writing a program that takes a Roman Numeral (up to 12 characters) and converts it to a decimal value. I am able to do this conversion successfully and read each value character by character, however my value is always 1000 greater than actual when the inputted string is not 12 characters, which I've determined is due to an extra loop through the evaluate subroutine (if no matches are made, it enters the process for converting M = 1000).
I assume it has something to do with the way I reading the user's string when less than 12 characters. It is my understanding that the read string system call code proceeds until it reaches a '\n' character, and converts that character and the rest of its empty space to 0 characters, so checking if the next character is not equal to 0 should work as I do not expect 0 to be in the user's input. I do realize I can fix my code by jumping to tailLoop if no match is made during "evaluate", but I would like to understand why the code I have currently isn't working.
The following code does not contain much of my program (would be quite long to post in full), only enough to understand the logic processes I am trying to use. This is homework in case it flavors how you want to answer the question.
# Program to translate Roman Numerals to decimal values
.data
numeralString:
.space 13
# End Strings
.text # Begin Program
.globl main
main:
li $v0, 8 # read string from user at next syscall
la $a0, numeralString
li $a1, 13
syscall
la $t0, numeralString # take input string and store in $t0
move $t1, $t0 # creating a copy of base register
lb $t2, 0($t0) # loads first byte (character) into $t2
jal evaluate # calls evaluate subroutine. String passed via $t0 (first byte/character specified in $t2)
# interger value returned via $v1
li $v0, 1 # print result value from $v1 at next syscall
move $a0, $v1
syscall
exit: # Exit Program in next syscall
li $v0, 10 # exit program in next syscall
syscall
evaluate: # matches numeral in string to correct subroutine
lb $t3, 1($t0)
beq $t2, 'M', mChar
mChar:
addi $v1, $v1, 1000
# beq $t3, 'C', cSlot
j tailLoop
tailLoop:
move $t2, $t3 # $t2 now holds next character of string
addi $t0, $t0, 1
bnez $t2, evaluate # Go back to evaluate if next character exists
jr $ra
It is my understanding that the read string system call code proceeds until it reaches a '\n' character, and converts that character and the rest of its empty space to 0 characters
No.
If you look at the spim source code, you'll see that the read_input function which is called in case of a syscall
Simulate[s] the semantics of fgets (not gets) on Unix file.
According to CPlusPlus.com:
A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str.
This is confirmed by examing the spim code.

Why load address works different on words and labels with strings?

​Hi,
I just had a quick question. Let's say I have 2 labels string and word with string being a label associated with a string and word being an actual word with a 32 bit integer stored in it. Now let's say I use a syscall to print string using the label string and I use load address with register a0, it will print the string. However why doesn't it print the address, since this is load address. On the other hand if I do the exact same thing but instead of using the string label I use the word label I am now instead going to print the actual address. I was wondering why it works this way.
Thanks for your time
Varun G.
I think you are misinterpreting syscalls. You issue a certain syscall to do different things.
To print a string you issue a syscall 4 ($v0 = 4). This service prints the string pointed by the address given in $a0 which you should previously load.
To print an integer you issue a syscall 1 ($v0 = 1). This service prints the integer stored at $a0. This integer may be seen as an address if you have loaded it with la pseudoinstruction.
So if you have the following snippet:
.data
str: .asciiz "hello!"
.text
la $a0, str
li $v0, 1
syscall # This will print the starting address of the string
li $v0, 4
syscall # This will print the contents of the string pointed by label str
it will print the address of the beginning of the string and also its contents.

MIPS Error: Not outputting prompts on new line

I'm trying to design a basic calculator with MIPS. I promt the user for the first operand, the operator, and then the second operand. I get and store the first operand, but after the user enters the operator the prompt for the second operand appears on the same line, immediately after the user's input. Here's a sample of what I mean:
Enter first number: 8
Select operator: -Enter second number: 3
Result: 5
-- program is finished running (dropped off bottom) --
The "Enter second number" was printed right after the minus sign. I use read string, with length of string = 2 to get the operator. Here's the relevant code for that:
GetOperator:
la $a0, prompt2 #Load prompt 2
add $v0, $zero, 4 #Load syscall 4
syscall
la $a0, operator
add $a1, $zero, 2
add $v0, $zero, 8 #Load syscall 8
syscall #Store the input string to memory
jr $ra
"operator" is a .word variable I declared under .data. I then use a syscall 4 to print the next prompt. I think there's just some subtle thing going on here that I'm missing. I'm still quite new with MIPS, so any pointers would be awesome.
You could print a carriage return / linefeed sequence before the "Enter second number" string.
# 13=carriage return, 10=linefeed, 0=null terminator
CRLF: .byte 13,10,0
Use syscall 4 to print it.