我很难弄清楚从哪里开始这个项目。我需要在PLP中编写代码,这是回文检查器。其任务是编写一个程序,通过UART接收字符串,检查该字符串是否为回文,然后使用打印函数打印"no“的”yes“。我已经给了一个模板,我要遵循的时候,创建程序。
模板项目文件包含需要实现的六个函数存根。从主循环调用五个函数,从“period_check”调用第六个函数:在模板文件中,它包含了每个函数需要做什么以及应该如何实现的描述。我试图填写一些,但我认为我没有走上正确的轨道。请帮助。
*我已经输入了这么多的代码,但是它没有打印出正确的输出*它输出的所有内容都是no,而非回文则是no,回文是的。
.org 0x10000000
# Initializations
# NOTE: You may add initializations after line 10, but please do not
# remove or change the initializations to $sp, $s0, $s1, or $s2
li $sp, 0x10fffffc # Starting address of empty stack
li $s0, 0xf0000000 # UART base address
li $s1, array_ptr # Array head pointer
li $s2, array_ptr # Array tail pointer
####################################################################
# Do not make changes to the jump to main, the allocation of
# memory for the array, or the main loop
####################################################################
j main
nop
array_ptr: # Label pointing to 100 word array
.space 100
main:
jal poll_UART
nop
jal period_check
nop
jal space_check
nop
jal case_check
nop
jal array_push
nop
j main
nop
####################################################################
# ******************************************************************
####################################################################
# The "poll_UART" function should poll the status register of the UART.
# If the 2^1 bit position (ready bit) is set to 1 then it
# should copy the receive buffer's value into $v0 and send
# a clear status command (2^1) to the command register before
# returning (a return statement is already included). In order to
# receive full credit, $s0 must contain the base address of the UART
# and must be used with the appropriate offsets to access UART
# registers and buffers
poll_UART:
lw $t1, 4($s0)
li $t2, 0b10
and $t3, $t1, $t2
beq $t3, $0, main
nop
lw $v0, 8($s0)
sw $t2, 0($s0)
jr $ra
nop
# The "period_check" function should check if the current character ($v0)
# is a period ("."). If it is a period then the function should go to the
# label, "palindrome_check". If the character is not a period then it
# should use the included return.
period_check:
li $t0, 0x2E
beq $v0, $t0, palindrome_check
nop
# The "space_check" function should check if the current character ($v0)
# is a space (" "). If it is then it should jump to "main" so
# that it skips saving the space character. If not it should
# use the included return.
space_check:
li $t4, 0x20
beq $t4, $v0, main
jr $ra
nop
# The "case_check" function should perform a single inequality check.
# If the current character ($v0) is greater than the ASCII value of 'Z',
# which indicates the current character is lowercase, then it should convert
# the value of $v0 to the uppercase equivalent and then return. If the
# current character ($v0) is already uppercase (meaning the inequality
# mentioned before was not true) then the function should return without
# performing a conversion.
case_check:
li $t5, 0x5A
slt $t6, $v0, $t5
li $t7, 1
beq $t6, $t7, convert
convert:
addiu $v0, $v0, -32
jr $ra
nop
# The "array_push" function should save the current character ($v0) to the
# current location of the tail pointer, $s2. Then it should increment the
# tail pointer so that it points to the next element of the array. Last
# it should use the included return statement.
array_push:
sw $v0, 0($s2)
addiu, $s2, $s2, 4
jr $ra
nop
# The "palindrome_check" subroutine should be jumped to by the period
# check function if a period is encountered. This subroutine should contain
# a loop that traverses the array from the front towards the back (using the
# head pointer, $s1) and from the back towards the front(using the tail
# pointer, $s2). If the string is a palindrome then as the array is traversed
# the characters pointed to should be equal. If the characters are not equal
# then the string is not a palindrome and the print function should be used
# to print "No". If the pointers cross (i.e. the head pointer's address is
# greater than or equal to the tail pointer's address) and the compared
# characters are equal then the string is a palindrome and "Yes" should be
# printed.
#
# Remember to restore the head and tail pointers to the first element
# of the array before the subroutine jumps back to main to begin processing the
# next string. Also, keep in mind that because the tail pointer is updated at
# the end of "array_push" it technically points one element past the last
# character in the array. You will need to compensate for this by either
# decrementing the pointer once at the start of the array or using an offset
# from this pointer's address.
palindrome_check:
addiu $s2, $s2, -8
move $s3, $s1
subu $s6, $s2, $s3
beq $s6, $0, palindrome
nop
check_loop:
lw $s4, 0($s3)
lw $s5, 0($s2)
bne $s5, $t0, not_palindrome
nop
adjust_pointers:
addiu $s2, $s2, -4
addiu $s3, $s3, 4
slt $t8, $s3, $s2
bne $t8, $t0, check_loop
nop
j palindrome
nop
palindrome:
li $a0, 1
call project3_print
move $s2, $s1
j main
not_palindrome:
li $a0, 0
call project3_print
move $s2, $s1
j main
nop
发布于 2022-09-20 15:44:30
好吧,这只是我的观点,但你绝对没有走上正确的轨道。
您显示的控制流是有问题的。
要了解其中一个原因,试着用C语言或任何其他你知道的语言写同样的东西,因为使用的是非本地的goto,其中一个过程跳转(不调用)到另一个过程。
此外,确定输入是否为回文不是对每个输入字符执行的一次性步骤的固定序列。
您将(1)需要存储字符以便以后进行比较,(2)需要一个决策点,在那里您可以确定(并打印)是的,或者不是的。您没有任何控制结构。
通过UART接收字符串,检查该字符串是否为回文,然后使用打印函数打印"no“的”是“。
是的,您的main
应该反映您所得到的上述描述:
如果该字符串是“no”characters
换句话说,您可能有如下内容:
int len = input_string();
if ( check_palindrome(len) ) {
print "yes";
else
print "no"
建议你用C语言或其他你知道的语言写,然后把它翻译成程序集。
另外,我们要考虑的是,我们编写的一些函数是返回值的函数,而不是不返回值的过程。返回一个值,以便main
可以采取不同的操作过程(例如,打印是和否),要比使用非本地的goto从子例程中改变控制流要好得多。
如果你的指导/课程给了你这个main
,并且推荐了非本地的goto,那将是非常可悲的。
我同情你和你的同学,因为这是我在很长一段时间里见过的最糟糕的教学集会之一。
array_ptr: # Label pointing to 100 word array
.space 100
标签名具有误导性。这个空间用作单词数组,而不是指向数组的指针。存储保留为25个字,因为.space
以字节为单位操作,而单词则为4个字节。因此,注释完全错误。
使用jal
的各种“函数”都是单一使用函数,因此在这个任务中实际上根本不需要函数。这些“函数”也相互连接并返回主函数,而不是像结构化编程中那样正确地返回。因此,这就是我们所称的意大利面条代码--这样的代码很难解释,而其他语言甚至懒得提供这种流控制的原因之一。
当输入元素仅为字符时,所使用的数组存储整个单词,因此这是无害的,但没有必要。
beq $t6, $t7, convert
convert:
这种控制结构永远不会在两个选项之间进行选择,它将始终转换。为什么会自动转换?因为在$t6为真的情况下,它将分支到convert:
,而如果$t6不为真,它就会掉到convert:
,所以在这两种情况下,相同的位置都会运行相同的代码。
您应该能够在调试期间观察到这一点。
调试提示
了解您的数据。调试时您应该知道数组的地址。您可以在执行过程中找到这一点,例如在li ... array_ptr
(顺便说一下,该操作码应该是la
)之后查看一个寄存器,但是不管它是否有效,您都可以在运行第一条指令之前观察数据部分及其布局。
一步一步地调试其他语言的代码,验证每一行之间的程序状态。在MIPS程序集中,程序状态在行间变化不大--通常这很简单--通常每条指令只更改一个寄存器或一个内存位置--但您必须验证这种更改是否如您所期望的那样。一旦程序的第一部分正确地将字符存储到数组中,您就可以使用断点功能在回文检查例程上停下来,然后只从那里开始执行一步。
首先使用最小的可能输入,(在最简并的情况下是空字符串,但您可能不是在处理这些输入)可能尝试一个字母输入(应该是回文). (一旦工作),尝试两个字母输入。正如我所说的,首先要确保字符值被正确地放置在数组中,并且只有在验证了这一点之后,才继续调试回文检查代码。
https://stackoverflow.com/questions/73788957
复制相似问题