Code:
.data
buf: .space 256
good: .asciiz "The string is a palindrome! \n"
bad: .asciiz "The string is not a palindrome. \n"
.text
main: la $a0, buf #load the string into $a0
li $v0, 8
syscall
li $t0, 0 #$t0 will be the string length counter
b tolower #branch tolower to lowercase all chars
rmain1: #point to return to main after tolower
li $t1, -1 #bottom character counter
li $t5, 1 #success indicator (1 for success, -1 else)
b check #branch to check to see if string is a palindrome
rmain2:
beq $t5, -1, isnt #if $t5 is -1, string is not a palindrome
beq $t5, 1, is #if $t5 is 1, string is a palindrome
isnt: la $a0, bad #load message 'bad'
b end #branch to end
is: la $a0, good #load message 'good'
end:
li $v0, 4 #print result message
syscall
li $v0, 10 #exit program
syscall
tolower:
#convert chars to lower case,
#non-alphanum's to ~ (so they will be ignored),
#and count the length of the string (stored in $t0)
lb $t1, buf + 0($t0) #load a byte from the string
beq $t1, 0x00, rmain1 #if it is null, end of string is found
#return to rmain1 to finish prog. execution
bgeu $t1, 0x7b, nlow #if byte is >= 0x7b it is not a lower case char
bleu $t1, 0x60, nlow #if byte is <= 0x60 it is not a lower case char
retlen: #point to return after altering a byte
sb $t1, buf + 0($t0) #store the final byte back in its location
addi $t0, $t0, 1 #add one to the string lenght counter
b tolower #loop back to analyze next byte
nlow: #not a lower case number
bgeu $t1, 0x5b, nalph #if byte is >= 0x5b, it is not an alpha-num char
bleu $t1, 0x40, chnum #if byte is <= 0x40, check and see if its a number
add $t1, $t1, 0x20 #other wise, its an upper-case letter, add 0x20 to
#it to make it a lower case letter
b retlen #return to the 'tolower' loop to store the byte
chnum: #check to see if its a number
bgeu $t1, 0x3a, nalph #if byte is >= 0x3a, it is not an alpha-num char
bleu $t1, 0x2f, nalph #if byte is <= 0x2f, it is not an alpha-num char
b retlen #otherwise, it is a lower case letter, just return
#to the 'tolower' loop and leave byte unchanged
nalph:
li $t1, 0x7e #not alphanum, set to ~ so it will be ignored
b retlen
check: #check if string is a palindrome
addi $t0, $t0, -1 #minus one from the top byte counter to init. it
addi $t1, $t1, 1 #add one to the bottom byte counter to init. it
bleu $t0, $t1, rmain2 #if the top counter is less then the bottom one,
#return to main, comparing is done
rtop: lb $t2, buf + 0($t0) #load top byte
beq $t2, 0x7e, nextop #if top char is a '~' or a NULL, go to nextop
beq $t2, 0x00, nextop #to incriment the top counter
rbot: lb $t3, buf + 0($t1) #same proceedure (as above) for the bottom char
beq $t3, 0x7e, nexbot
beq $t3, 0x00, nexbot
beq $t2, $t3, check #if the chars are the same, go to top of loop
li $t5, -1 #else, set success indicator to -1 and go to rmain2
b rmain2
nextop: addi $t0, $t0, -1 #decrease top counter by one, go to rtop to load a
b rtop #new char
nexbot: addi $t1, $t1, 1 #increase top counter by one, go to rbot to load a
b rbot #new char