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
Related
So when I call this function for a value in my array, it prints out a garbage value then on the next line what I actually want to print. When I enter a value not in the array it errors out. I am new to this so could be something stupid
.data
array: .word 2,3,1,5,6,7,1,4,8,8 #elements
N: .word 10 # 10 elements
key: .word 0
int: .word 9
search:
la $a0, array
la $t0, N
lw $t0, ($t0)
sll $t0, $t0, 2
addi $t0, $t0, -4
add $a1, $a0, $t0
la $a0, array
jal isort #insert function from other function
li $v0, 4
la $a0, enterKey # Display text
syscall
li $v0,5 # read input
syscall
sw $v0, key
syscall
move $t0, $s0
lw $t1, N
lw $t2, ($t0)
li $t3,0 # $t3 i = 0
lw $t4, int
lw $t5, key
lw $t6, int
loopKey:
beq $t3, $t1, endKey # if i = n, loop ends
bne $t2, $t5, condKey # if the elements are not equal
move $t4, $t3 # assign index found to variable
j endKey
condKey:
addi $t3, $t3, 1 # i++
addi $t0, $t0, 4
lw $t2, ($t0)
j loopKey
endKey:
beq $t4, $t6, noKey #does not appear to even work???
li $v0, 4
la $a0, keyFmsg
syscall
li $v0, 1
add $t4, $t4, 1 # have to add 1 for location not index
add $a0, $zero, $t4 # prints the location
syscall
j displayMenu
noKey: #not working idk why
li $v0, 4
la $a0, keyNFmsg
syscall
j displayMenu
So my program is running into an infinite loop when printing words:
It's printing the first character of my array, but it's not incrementing to the next character. I'm not sure what exactly to do at this point: adding i * 4 + 1 ran into an exception and i * 4 only prints the first character. Suggestions?
#Prints original string
#Prints each word in string
#Prints word count for each string
#Prints final concatenated word count
.data
phrases: .word string1
.word string2
.word string3
.word string4
.word string5
.word string6
.word string7
.word string8
.word string9
.word string10
.word string11
.word string12
numPhrases:
.word 12
string1: .asciiz "Four-score"
string2: .asciiz "and seven years"
string3: .asciiz "ago, our"
string4: .asciiz "fathers"
string5: .asciiz "brought forth on"
string6: .asciiz "this continent a"
string7: .asciiz "new nation, "
string8: .asciiz "conceived in liberty"
string9: .asciiz "and dedicated to the"
string10: .asciiz "proposition"
string11: .asciiz "that all men are"
string12: .asciiz "created equal."
# Your code goes below this line
origString: .asciiz "The original string:\n"
words: .asciiz "Words found in the string:\n"
wordCount: .asciiz "Word count is now "
finalCount: .asciiz "Final word count is "
newline: .asciiz "\n"
.text
main:
# Function prologue
addiu $sp, $sp, -24 # allocate stack space -- default of 24 here
sw $fp, 0($sp) # save caller's frame pointer
sw $ra, 4($sp) # save return address
addiu $fp, $sp, 20 # setup main's frame pointer
#Initial loop conditions
la $t0, numPhrases
lw $s0, 0($t0) #$s0 = numPhrases
la $s1, phrases #$s1 now equals arr of strings
addi $s2, $zero, 0 #i = 0, loop each char of a string
addi $s3, $zero, 0 #j = 0, loop each address of phrases
addi $t2, $zero, 0 #word count = 0
loopPhrases:
#for (j < phrases.length)
# print phrases[j];
#j++
#exit condition
slt $t1, $s3, $s0 #$t1 = j < numPhrases
beq $t1, $zero, endPhrases #if j < numPhrases, end
#loop body
#print original string
la $a0, origString
addi $v0, $zero, 4
syscall
add $s4, $s1, $s3 #$address of phrases[j]
lw $s5, 0($s4) #$s5 = phrases[j]
addi $a0, $s5, 0
addi $v0, $zero, 4
syscall #print string
#newline
la $a0, newline
addi $v0, $zero, 4
syscall
#Print words
la $a0, words
addi $v0, $zero, 4
syscall
loopWords:
#while (charAt(i) != '\n', '\t', or ' '
#and i < string.length())
# print charAt(i)
# i++
#exit condition
add $t5, $s2, $s1 #address of string[i]
lw $s5, 0($t5) #string[i]
beq $s5, $zero, endWords #if string[i] == nul, end
#If whitespace, jump
addi $t1, $zero, 9 #$t0 = 9(tab)
beq $t0, $t1, nextWord #$t0 = tab
addi $t1, $zero, 10 #$t0 = 10(newline)
beq $t0, $t1, nextWord #$t0 = newline
addi $t1, $zero, 32 #$t0 = 32(space)
beq $t0, $t1, nextWord #$t0 = space
#Print word
lb $a0, 0($s5)
add $v0, $zero, 11
syscall
#i++
add $s2, $s2, $s2
add $s2, $s2, $s2
j loopWords
nextWord:
la $a0, newline
addi $v0, $zero, 4
syscall
addi $t2, $t2, 1 #wordCount++
addi $s2, $s2, 1 #i++
j loopWords
endWords:
#Print word count
la $a0, wordCount
addi $v0, $zero, 4
syscall
la $a0, 0($t2)
addi $v0, $zero, 1
syscall
#newlines
la $a0, newline
addi $v0, $zero, 4
syscall
la $a0, newline
addi $v0, $zero, 4
syscall
#j++
addi $s3, $s3, 4
j loopPhrases
endPhrases:
#Print final count
la $a0, finalCount
addi $v0, $zero, 4
syscall
la $a0, 0($t2) #word count
addi $v0, $zero, 1
syscall
done: #Epilogue for main -- restore stack & frame pointer
lw $ra, 4($sp) #get return address from stack
lw $fp, 0($sp) #restore the caller's frame pointer
addiu $sp, $sp, 24 #restore the caller's stackpointer
jr $ra #return to caller's code
The following is my code for a MIPS assembly program that is intended to remove vowels from an input string and then print the new string. As it stands, the program simply does not remove the vowels and just reprints the same string that was input.
.text
.globl main
main:
# display prompt
li $v0, 4
la $a0, prompt
syscall
# accept input string
li $v0, 8
la $a0, str
li $a1, 82
syscall
li $t0, 0 # add a null to the bottom of the stack
subu $sp, $sp, 4
sw $t0, ($sp)
li $t1, 0 # initiate index
pushloop:
lbu $t0, str($t1) # (I think the program is placing a zero in $t0 here, thus causing it to branch immediately to poploop, which then branches to the end since only the null has been pushed onto the stack)
beqz $t0, poploop # once we reach null char, finish
subu $sp, $sp, 4
sw $t0, ($sp)
addiu $t1, $t1, 1
j pushloop
nop
# $t1 is not reset
poploop:
lw $t0, ($sp)
addu $sp, $sp, 4
beqz $t0, done # once we reach null char, finish
nop
# check if vowel
li $t2, 0x61 # a
beq $t0, $t2, vowel
nop
li $t2, 0x65 # e
beq $t0, $t2, vowel
nop
li $t2, 0x69 # i
beq $t0, $t2, vowel
nop
li $t2, 0x6F # o
beq $t0, $t2, vowel
nop
li $t2, 0x75 # u
beq $t0, $t2, vowel
nop
# if not a vowel, store it at current index in string
sb $t0, str($t1)
j decrement
nop
vowel: # if vowel, remove character
li $t0, 0
sb $t0, str($t1)
decrement:
addiu $t1, $t1, -1 # decrement index
j poploop
nop
done:
li $v0, 4
la $a0, str
syscall
li $v0, 10 # exit program
syscall
nop
.data
str: .space 82
prompt: .asciiz "Input a string:\n"
So. I took a look at what you've writen and I've fixed it.
My first thought is I don't know what you are doing with the stack and stack pointer ($sp). It didn't seem necessary so I took it out.
Next is that the approach is wrong. Your approach is to search the string and replace every lower-case vowel (or at least 'a', 'e', 'i', 'o' and 'u') with a 0. This will not work.
If you think about a typical C string, they are delimeted by a 0, so if you take the string My name is Jeoff and apply your algorithm you will get My n\0m\0 \0s J\0\0ff which of course will print as My n.
So instead, I chose a separate algthm that chooses to not store anything in the case of a vowel and instead shift all following characters over by 1. In so doing we can easily remove all vowels from a string without requiring a secondary buffer.
Take a look below:
.text
.globl main
main:
# display prompt
li $v0, 4
la $a0, prompt
syscall
# accept input string
li $v0, 8
la $a0, str
li $a1, 82
syscall
li $t1, 0 # initiate index
li $t3, 0 # vowel count
poploop:
lb $t0 str($t1)
# check if vowel
li $t2, 'a' # a
beq $t0, $t2, vowel
nop
li $t2, 'e' # e
beq $t0, $t2, vowel
nop
li $t2, 'i' # i
beq $t0, $t2, vowel
nop
li $t2, 'o' # o
beq $t0, $t2, vowel
nop
li $t2, 'u' # u
beq $t0, $t2, vowel
nop
# if not a vowel, store it at current index in string less vowel count
sub $t2, $t1, $t3
sb $t0, str($t2)
j next
nop
vowel: # if vowel, inc count
addi $t3, $t3, 1
next:
addi $t1, $t1, 1
beqz $t0, done # once we reach null char, finish
nop
j poploop
nop
done:
li $v0, 4
la $a0, str
syscall
li $v0, 10 # exit program
syscall
nop
.data
str: .space 82
prompt: .asciiz "Input a string:\n"
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).
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.