Find number of spaces in a string mips assembly - string

So I have a string in .data. The string is "e8 e r e r c e r g r r r g,".
I want to find the number of spaces in the string. It is stored in $a0, but in a different file and both the file I am writing the method for finding spaces and the file with the string is linked using the "include" feature.
My code isn't working even though I think the idea is right.
my code so far
lb $s1, ($a0)
la $s2 ' '
li $v0, 0
findNumSpaces:
beq $s1, $zero, printNumSpaces
beq $s1, $s2, isSpace
addi $a0, $a0, 1
lb $s1, ($a0)
j findNumSpaces
isSpace:
addi $v0, $v0, 1
addi $a0, $a0, 1
lb $s1, ($a0)
j findNumSpaces
printNumSpaces:
li $v0, 1
syscall

When it finds a space, it doesn't increment $a0 or load the new value of $s1.
It doesn't check for the end of the string, so it will loop forever.

Related

reading multi-digit numbers from a char string in MIPS (assembly code)

I'm trying to read a string from a user in order to evaluate an expression. For example I want to compute ((2-(8*9))1-4)). To accomplish this, I convert the characters of the numbers read to the actual number they represent while saving them back into the string with the code below. My algorithm works great when I input digits of (0-9) in between operation commands ' - ( ) / '. But I need to make it work when inputting multi-digit numbers in my string. For example, ((20-(8*91))*1-43)). I know the algorithm to convert, lets say 3 1 4 into 314, but my question is, how can I insert it back into my byte string while maintaining the same order on the following characters? I've tried many ways, but can't get it to work. thanks in advance
.data
expression: .space 110 # to store string
stack: .space 110 # to help with operations
.text
#______reading string from user
li $v0, 8
li $a1, 100
la $a0, expression
syscall
#_____________________________
#___count number of characters in string
la $s0, expression #s0 = adress of string
li $t1, 0 #t1 = # characters
loopcounter:
lb $t0, ($s0)
beq $t0, '\n', outcounter
addi $t1, $t1, 1
addi $s0, $s0, 1
j loopcounter
outcounter: #if you want to print the amount of characters in the string
#li $v0, 1
#move $a0, $t1
#syscall
#_______________________________________
#__convert number characters into integers
la $s0, expression #s0 = adress of string
li $t0, 1 #t0 loop counter
loopStringtoNum:
lb $t2, ($s0) #t2 = ASCII of a digit
blt $t2, '0', skipCharConversion
bgt $t2, '9', skipCharConversion
subi $t2, $t2, 0x30 #t1 = the digit
sb $t2, ($s0)
skipCharConversion:
addi $s0, $s0, 1
addi $t0, $t0, 1
ble $t0, $t1, loopStringtoNum #skip string to num loop
#_________________________________________

Removing extra spaces after i enter a string

Hi i was wondering if there was a simple way to remove the spaces i allocated for a string to be entered, or perhaps a way to not compare the empty space after the word. This program is a palindrome detector. Any suggestions would be great.
Ex. output:
racecar, not a palindrome because it has a few empty spaces.
aaaaaaaaaa is a palindrome because it has no empty spaces...
again just need a hotfix to remove the spaces after the word is inputted, or a way to ignore the spaces after the word. Thank You.
.data
intro : .asciiz "Lets See If Your Word is a Palinfrome!\n"
question: .asciiz "Please Enter up to a 10 Character word: "
Y_P: .asciiz "Yes it is!"
N_P: .asciiz "No Its Not!"
str1: .space 10
.text
.globl main
main:
li $v0, 4
la $a0, intro
syscall
li $v0, 4
la $a0, question
syscall
li $v0, 8
la $a0,str1
addi $a1,$zero,10
syscall
move $t0, $a0
palindrome:
addi $t0, $0, 0 # j = 0
length: add $t2, $a0, $t0 # $t2 = &array[j]
lb $t2, 0($t2) # $t2 = array[j]
beq $t2, $0, done # end of string?
addi $t0, $t0, 1 # j = j+1
j length
done: addi $t0, $t0, -1 # j = j-1
addi $t1, $0, 0 # i = 0
loop: slt $t2, $t1, $t0 # $t2 = 1 if i < j
beq $t2, $0, yes # if !(i < j) return
add $t2, $a0, $t1 # $t2 = &array[i]
lb $t2, 0($t2) # $t2 = array[i]
add $t3, $a0, $t0 # $t3 = &array[j]
lb $t3, 0($t3) # $t3 = array[j]
bne $t2, $t3, no # is palindrome?
addi $t0, $t0, -1 # j = j-1
addi $t1, $t1, 1 # i = i+1
j loop
yes: # yes a palindrome
addi $v0, $0, 1
li $v0, 4
la $a0, Y_P
syscall
li $v0, 10
syscall
j yes
jr $ra
no: # not a palindrome
addi $v0, $0, 0
li $v0, 4
la $a0, N_P
syscall
li $v0, 10
syscall
j no
jr $ra

Reverse words of a sentence in mips

You are given a string, like "hello what is your name?"
You have to reverse the words, using a recursive function.
So the result of the example string is "name? your is what hello"
The language is MIPS assembly.
Here is what I have done so far: (The code doesn't end unfortunately :| and I can't find the issue)
.macro print_int(%arg)
li $v0, 1
add $a0, %arg, $zero
syscall
.end_macro
.macro print_string(%arg)
move $t9, $a0
li $v0, 4
add $a0, %arg, $zero
syscall
move $a0, $t9
.end_macro
.text
la $s0, string
li $s1, 32 # space
la $t8, space
sub $s0, $s0, 1
sb $s1, 0($s0)
# find the length of the string
move $t0, $s0 # $t0 = i = the iterator
L1: lb $t1, 0($t0) # $t1 = i'th char of the string
beq $t1, 0, Exit # if string[i] == null, Exit
addi $t0, $t0, 1 # i++
j L1
Exit:
sub $s3, $t0, $s0 # $s3 is the length of the string
# Set arguements
move $a0, $s0
move $a1, $t0 # endFlag = length of the string
jal reverse # call the function
li $v0, 10
syscall # exit
reverse:
# save registers
sub $sp, $sp, 12
sw $ra, 0($sp)
sw $a0, 4($sp)
sw $a1, 8($sp)
bgt $a1, $s0, L2 # base case
add $sp, $sp, 12
jr $ra
# find a word in the string
L2:
add $t0, $zero, $a1
add $t3, $a0, $s3 # address of last character of the string
Loop:
lb $t4, 0($t3) # chracter from the string
seq $v0, $s1, $t4 # if space
ble $t3, $a0, Exit_Loop # if first of string
beq $v0, 1, Exit_Loop # if character was space
sub $t3, $t3, 1
j Loop
Exit_Loop:
sb $zero, 0($t3)
add $t3, $t3, 1
print_string($t3)
print_string($t8)
#recursive call
move $a1, $t3
jal reverse
# load registers
lw $ra, 0($sp)
lw $a0, 4($sp)
lw $a1, 8($sp)
add $sp, $sp, 12 # release the stack
jr $ra
.data
string: .asciiz "hello what is your name?"
newline: .asciiz "\n"
space: .asciiz " "
Your code does not stop from entering the function recursive even if the string is empty ($t3 == $a0 + 1).
Here's a quick fix: replace your code:
Exit_Loop:
sb $zero, 0($t3)
add $t3, $t3, 1
print_string($t3)
print_string($t8)
#recursive call
move $a1, $t3
jal reverse
with:
Exit_Loop:
sb $zero, 0($t3)
add $t4, $t3, 1
print_string($t4)
print_string($t8)
ble $t3, $a0, Exit_Func
#recursive call
move $a1, $t4
jal reverse
Exit_Func:
Also, please notice that your macro print_int doesn't store/restore the value of $a0, also even in print_string you store/restore $a0 using $t9, that's still dangerous since according to the MIPS32 ABI the values in register $t[0-9] are not guaranteed to be reserved during a syscall (while in $s[0-7] it is guaranteed).

MIPS randomized word scrambler

I am trying to write code that uses the MARS (my MIPS simulator) pseudorandom number generator to pick a random char in the string, take it out of memory and into a register, and replace that char in memory with an asterisk, '*'.
So far, it only scrambles part of the word, and it's driving me insane. I can't find what in this code isn't working. I don't even need a direct answer, just hints/tips would be SO helpful.
Here is the code:
#this loop extracts a char at random from a string in memory, stores it in a register, and replaces the char in the string with an asterisk '*'
.data
.align 2
string0: .ascii "Tyler\n"
.align 2
endString: .asciiz "Loop completed!\n"
.align 2
scrambleString: .asciiz
.text
#counter
li $t0, 5
#pointer to string0
la $s0, string0
loop2:
#is counter = 0? go to loop3 if so
beq $t0, $0, loop3
#seed & prepare randomized number generator
li $v0, 30
syscall
li $v0, 40 #sets seed
syscall
#generates random number in $a0, with the coUnter $t0 being the upper bound
addi $a1, $t0, 1
li $v0, 42
syscall
#add STRING POINTER by random number in $a0, store this new address in $t1
#addi $a0, $a0, 1
add $t1, $s0, $a0
#srlv $t1, $s0, $a0
#isolates that bytesized char, puts it into $t2
lbu $t2, ($t1)
#beq $t2, 0x5c, loop2
#replaces char in original string with "*"
li $t3, 0x2a
sb $t3, ($t1)
beq $t1, $t3, loop2
#decrement counter
addi $t0, $t0, -1
#loop return
j loop2
loop3:
la $a0, string0
li $v0, 4
syscall
li $v0, 10
syscall
You are resetting the random number seed on every iteration of
your loop (loop2:).
Syscalls 40 and 42 each take 2 parameters which should be in $a0 and
$a1. See here.
The temporary registers $t0,...,$t9 get altered by each
syscall. You should be using the callee saved registers
$s0,...$s8 instead.

Complications in MIPS code of Recursive Reversal of a string

I have written this MIPS code of recursive reversal of a string. However, the output is coming out to be the same that has been input by the user. Can someone please help me out and indicate where am I going wrong? Please reply as soon as possible.
# Program to reverse a string input by the user
.data
.align 2
array: .space 50
input: .asciiz "Enter a string: "
output: .asciiz "\nThe reversed string is: "
.text
.globl main
main:
addi $s0, $zero, 50
addi $t0, $zero, 0
la $a0, input
li $v0, 4
syscall
la $a0, array
li $v0, 8
syscall
initiate:
add $t0, $a0, $zero # initial address
add $t1, $zero, $zero # count=0
add $t2, $zero, $zero # i=0
la $t0, array # base address of the array
add $t3, $t0, $t2 # & array[i]
loop:
lb $t3, 0($t3) # fetch array[i]
beqz $t3, EndOfString # loop exits if it is a null character;array[i] !='\0'
bne $t3, $0, continue # otherwise loop continues
add $t1, $t1, 1 # count++
continue:
add $t2, $t2, 1 # i++
j loop
addi $a1, $zero, 50
jal StringReversal
EndOfString:
la $a0, output
li $v0, 4
syscall
la $a0, array
li $v0, 4
syscall
li $v0, 10
syscall
StringReversal:
add $t0, $a0, $zero # initial address
add $t4, $zero, $zero # j = start = 0
addi $t5, $a1, -1 # k = end-1
SwapLoop:
add $t6, $t0, $t4
lb $t7, 0($t6) # load byte array[start]
add $t8, $t0, $t5
lb $t9, 0($t8) # load byte array[end-1]
sb $t7, 0($t8) # array[end-1] = array[start]
sb $t9, 0($t6) # array[start] = array[end-1]
addi $t4, $t4, 1 # j++
addi $t5, $t5, -1 # k--
slt $t9, $t5, $t4
beqz $t9, SwapLoop
jr $ra
# Program to reverse a string input by the user
.data
.align 2
array: .space 50
input: .asciiz "Enter a string: "
output: .space 50
size: .word 49
.text
j main
length:
# return length of the input string
# $a0 - address of string
# $v0 - length of the string
move $v0, $zero # set $v0 to 0
length_loop:
lb $t0, 0($a0)
beqz $t0, length_end
addi $v0, $v0, 1
addi $a0, $a0, 1
b length_loop
length_end:
subi $v0, $v0, 1
jr $ra
reverse:
# $a0 - address of string to reverse
# a1 - length of the string
# a2 - address of string where to store the reverse
addi $sp, $sp, -4
sw $ra, 0($sp)
bltz $a1, reverse_end
lb $t0, 0($a0)
subi $a1, $a1, 1
subi $a0, $a0, 1
sb $t0, 0($a2)
addi $a2, $a2, 1
jal reverse
reverse_end:
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
main:
addi $s0, $zero, 50
addi $t0, $zero, 0
la $a0, input
li $v0, 4
syscall
# read string from the user into $a0
la $a0, array
lw $a1, size
li $v0, 8
syscall
# reverse the string
jal length # $v0 contains length of string
la $a0, array
move $a1, $v0
add $a0, $a0, $a1 # pointer to the last character
la $a2, output
jal reverse
# print the reverse string
la $a0, output
li $v0, 4
syscall
Output:
Enter a string: hello
olleh
-- program is finished running (dropped off bottom) --
In your continue label, it looks as though j loop is called too early, and hence
addi $a1, $zero, 50
jal StringReversal
is never reached, hence the instructions in the StringReversal label are not performed.

Resources