Question: I have to write a program in the 5.2 PLPTool MIPS assembly language to interact with the UART to receive multiple strings of data, input
I have to write a program in the 5.2 PLPTool MIPS assembly language to interact with the UART to receive multiple strings of data, input them into an array, and use stacks to push and pop the values to determine if the strings are palindroms. The instructions are as follows:
The Task In this project, you will be writing a program that receives a string of characters via the UART, checks if this string is a palindrome, and then uses a print function to print either Yes or No. A palindrome sequence of characters (typically a word or phrase) that is the same both forwards and backwards. For this project, strings will be terminated using a period (.). You may assume that a string will contain at least one character in addition to a period. You will not need to handle empty strings or strings with only a period. Your program should be able to handle multiple strings sent one after another or concatenated together. For example, the string: abba. data. should print Yes followed by No on the next line. Spaces should be ignored when checking for a palindrome and the palindrome should not be case sensitive. For example, A nut for a jar of Tuna. would be considered a palindrome. Print Function A skeleton PLP project file is available to download on Blackboard. The PLP project includes a second ASM file titled, project3_print.asm. This ASM file contains the print function used in this project. PLPTool concatenates all ASM files within a PLP project into a single location in memory (unless additional .org statements have been added to specify different location for code). No changes to project3_print.asm should be made. When called, depending on the value in register $a0, the following string will be displayed on the simulated UART devices output. If $a0 contains a zero then No will be displayed and if $a0 contains a non-zero value (e.g. one) then Yes will be displayed. The print function is called using the following instruction: call project3_print To use the print function, your PLP program needs to initialize the stack pointer ($sp) before performing the function call (or any other operations involving the stack pointer). For this reason, the skeleton project file includes an initialization that sets the stack pointer to 0x10fffffc (the last address of RAM).
The call function to print the answer is a separate program that is pre-written and is only used to return the "Yes" or "No" strings within the UART. I have written up most of the code but it isn't working quite as expected and I just need help figuring out where I'm making mistakes.
My communication with the UART is working, I am able to skip spaces, convert capital letters to lowercase, and end the string collection when a period is read from the UART. My array is storing my values and I'm able to push those values onto my stack. From there is where I run into issues. I'm not sure if I'm popping my values into an array correctly or if I'm comparing my new array to the original array correctly. My program always returns no, even if I do enter a palindrome. I'm also not sure if it'll be able to accept multiple strings as per the instructions. I would greatly appreciate assistance with figuring out how to fix the last parts of my program. Thank you very much in advance! My code so far is:
.org 0x10000000
# Initialize stack
li $sp, 0x10fffffc
# Initialize UART Command Register (write-only)
li $s0, 0xf0000000
# Iniitalize UART Status Register (read-only)
li $s1, 0xf0000004
# Initialize UART Receive Buffer (read-only)
li $s2, 0xf0000008
array_ptr: # Label pointing to 100 word array
.space 100
li $a0, array_ptr # Assign array to register $a0
move $a1, $a0 # $a1 = address of array[0]
read_UART_status:
lw $t0, 0($s1) # Get UART status
li $t1, 0b10 # Create mask for second bit
and $t2, $t0, $t1 # Mask for ready bit
beq $t2, $zero, read_UART_status # If status is 0, read status again
nop
lw $v0, 0($s2) # Otherwise load bit value of receive buffer to register $v0
sw $t1, 0($s0) # Send clear status to command register
check_for_space:
li $s3, 0x20 # Assign space to register $s3
beq $v0, $s3, read_UART_status # If $v0 is a space, read the next value in the string
nop
check_for_uppercase:
li $t5, 0x41 # Assign hex value of uppercase A to register $t5
li $t6, 0x5A # Assign hex value of uppercase Z to register $t6
slt $t7, $t6, $v0 # Assign 0 to $t7 if $v0 hex value is less than or equal to uppercase Z
slt $t8, $v0, $t5 # Assign 0 to $t8 if $v0 hex value is greater than or equal to uppercase A
beq $t7, $t8, check_for_zero # If $t7 and $t8 are equal, go to label to check if the value is zero
nop
j check_for_period # Else, jump to check if $v0 is a period
nop
check_for_zero:
beq $t7, $zero, convert_to_lowercase # If $t7 is zero, jump to convert to lowercase letter
nop
j check_for_period # Else, jump to check if $v0 is a period
nop
convert_to_lowercase:
addiu $v0, $v0, 32 # Add 32 to the convert uppercase letter to lowercase letter
j store_in_array # Jump to add $v0 to the array
nop
check_for_period:
li $t9, 0x2E # Assign period to register $t9
beq $v0, $t9, main # If $v0 is a period, jump to main loop
nop
j store_in_array # If not a period, jump to add $v0 to the array
nop
store_in_array:
sw $v0, 0($a1) # Store value of $v0 into array
addiu $a1, $a1, 4 # $a1 = $a1 + 4
j read_UART_status # Return to read the next character in the string
nop
main:
move $a2, $a0 # Copy array into register $a2
li $t5, 0 # i = 0
push_loop:
lw $t7, 0($a2) # Get array[i]
push $t7 # Push $t7 into stack
addiu $t5, $t5, 1 # i = i + 1
addiu $a2, $a2, 4 # update array address
slt $s6, $a2, $a1 # $s6 = (i < size)
bne $s6, $zero, push_loop # If (i < size) continue push
nop
li $t5, 0 # Otherwise, reset i = 0
pop_loop:
pop $t7 # Pop $t7 from stack
sw $t7, 0($a2) # Store popped value to first element of array
addiu $t5, $t5, 1 # i = i + 1
addiu $a2, $a2, 4 # update array address
slt $s6, $a2, $s4 # $s6 = (i < size)
bne $s6, $zero, pop_loop # If (i < size) continue push
nop
check_if_palindrome:
beq $a2, $a0, assign_one # If array $s5 is equal to original array, jump to assign one
nop
assign_zero: # Otherwise, assign 0
li $a0, 0 # Assign 0 to $a0
call project3_print # Call function to print "No"
j read_UART_status # Return to read UART status
nop
assign_one:
li $a0, 1 # Assign 1 to $a0
call project3_print # Call function to print "Yes"
j read_UART_status # Return to read UART status
nop
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
