【问题标题】:Code to test if string is palindrome - MIPS测试字符串是否为回文的代码 - MIPS
【发布时间】:2016-02-21 01:40:16
【问题描述】:

我正在尝试在 MIPS 中编写一个程序来确定字符串是否为回文。程序应忽略用户输入字符串中的所有标点符号和空格。对于我的程序,以下字符串将被视为回文。

  1. “1 2 321”
  2. “女士。我是亚当。”
  3. “去挂意大利腊肠:我是烤宽面条。 !!!”

我无法弄清楚为什么我的程序无法运行。我对 mips 很陌生,这可能是我忽略或完全错误的简单事情。这是我的代码:

.data 
charCount: .byte 0
goAgain: .asciiz ""
userInput: .asciiz ""


.text
main:
    la $a0, userInput 
    li $a1, 50
    li $v0, 8
    syscall

endofstr:
    loop:
    lb $t1, ($a0)
    beqz $t1, next #branch if end of string
    addi $a0, $a0, 1 #increment byte address
    j loop

next:
    subi $a0, $a0, 2 #line a0 on the last character of the user string  
    loopNext:
    la $a2, userInput
    lb $t2, ($a2)
    lb $t3, ($a0)
    jal testValues


testValues:
    bgt $t2, 90, lt97
    j skipa
    lt97: blt $t2, 97, nextT2
    skipa:
    bgt $t2, 122, nextT2
    bgt $t2, 57, lt65
    j skipb
    lt65: blt $t2, 65, nextT2
    skipb:
    blt $t2, 48, nextT2
    #make t2 uppercase
    blt $t2, 97, skip_nextT2
    subi $t2, $t2, 32
    j skip_nextT2

    nextT2:
        addi $a2, $a2, 1
        lb $t2, ($a2)
        j testValues

    skip_nextT2:
    bgt $t3, 90, lt97b
    lt97b: blt $t3, 97, nextT3
    bgt $t3, 122, nextT3
    bgt $t3, 57, nextT3
    blt $t3, 48, nextT3
    blt $t3, 97, eval
    subi $t3, $t3, 32
    j eval

    nextT3:
        subi $a0, $a0, 1
        lb $t3, ($a0)
        j skip_nextT2

eval:
    beq $a0, $a2, isPali
    beq $t2, $t3, equal
    j notPali

    equal:
        subi $a0, $a0, 1
        addi $a2, $a2, 1
        lb $t2, ($a2)
        lb $t3, ($a0)
        j testValues
    #set T2 to be capital for easier work path. 

isPali:
    li $s7, 1
    j exit

notPali:
    li $s7, -1
    j exit

exit:

【问题讨论】:

  • Assembly 使用通用寄存器名称而不是变量名称,因此 cmets 和有意义的标签对于使代码可读性至关重要。
  • 为什么在下一个减2:?不应该是 1 来备份 z 字节吗?
  • At eval: beq $t2,$t3,equal 如果字符串是偶数个字符,则永远不会为真。它应该测试是否 t2>=t3。
  • 在nextT2:你需要测试a2>=a0是否为字符串结尾。在 nextT3:你需要测试是否 a0
  • 更正:忽略关于 beq $t2,$t3 的评论。我的意思是:在 eval: beq $a0,$a2,isPali 应该测试 a2>=a0。

标签: assembly mips palindrome


【解决方案1】:

这是我想出的答案。我重新启动它,以便我可以从一个清晰的头脑开始并完成它。这次也包括了很多 cmets。享受。感谢所有cmets的帮助。

.data 
userInput: .space 50
userInputx: .space 50
isPali: .asciiz " is a palindrome. :)\n\n"
notPali: .asciiz " is not a palindrome. :(\n\n"
goAgainMessage: .asciiz "Would you like to give it another try? (yes/no): "
goAgainInput: .space 4
exitMessage: .asciiz "Program Terminated. Good bye. "
startPrompt: .asciiz "\nEnter a string to see if it is a palindrome: "



.text
main:
    la $a0, startPrompt #ask the user for input. 
    li $v0, 4
    syscall
    la $a0, userInput #store the user input in this location
    li $a1, 50
    li $v0, 8
    syscall #get the user input. 

sanitize: #sanitize the data that is entered so that we only check 0-9, A-Z, and a-z (rules for assignment
    la $t1, userInputx
    loop:
        lb $t7, ($a0)
        beq $t7, 10, checkPali  #begin the checking process, byte by byte until you reach the last byte in the string.
        bgt $t7, 47, test1
        j notToInputx
        test1: blt $t7, 58, addToInputx
        bgt $t7, 64, test2
        j notToInputx
        test2: blt $t7, 91, addToInputx #multi tests to elimate characters by ascii defined decimal codes. 
        bgt $t7, 96, test3
        j notToInputx
        test3: blt $t7, 123, addToInputx
        j notToInputx
    addToInputx: #input x is what we store the sanitized string in. Char by Char
        bgt $t7, 96, makeCap
        j notCap
        makeCap: addi $t7, $t7, -32 #this is to make comparison case-insensitive. 
        notCap:
        sb $t7, ($t1)
        addi $a0, $a0, 1 #increment each memory location
        addi $t1, $t1, 1
        j loop
    notToInputx: #do not add char to new sanitized string
        addi $a0, $a0, 1 #increment user input
        j loop
    setEOS:
        #set end of string

checkPali:
    la $t4, userInputx
    #use t1 as the backwards one
    #li $a3, 127
    sb $zero, ($a0)
    addi $t1, $t1, -1   #decrement from end of $t1, increment from beginning of $t4
    loop3:          #they are the same string. Just starting from both ends

        lb $t3, ($t4)
        lb $t2, ($t1)   #load bytes for testing
        beq $t3, $t2, next  #continue the check if bytes are equal
        j notPaliX  #no need to check the rest of the string if bytes are not equal
        next: jal testLocation  #test to make sure we are not at last byte. 
              addi $t4, $t4, 1 #incrememnt t4 closer to middle
              addi $t1, $t1, -1 #decrememnt t1 closer to middle (from reverse)
              j loop3   #continue to next iteration of loop
        j notPaliX

    testLocation:
        #current address variables are $t3 (forward) and $a0 (backward)
        beq $t4, $t1, isPaliX
        addi $t1, $t1, -1
        beq $t4, $t1, isPaliX   #test to see if we need to check more characters
        addi $t1, $t1, 1    #when at the middle, address's are going to be either equal 
        jr $ra          #or a == (b-1)

    isPaliX:
        la $a0, userInput
        li $v0, 4   #this is what happens when input is a pali
        syscall
        la $a0, isPali
        syscall
        j goAgainX

    notPaliX:
        la $a0, userInput #this is what happens if input is not a pali
        li $v0, 4
        syscall
        la $a0, notPali
        syscall
        j goAgainX #simply for clarity. Not needed for control flow

    goAgainX:
        la $a0, goAgainMessage
        syscall
        li $a1, 4
        li $v0, 8
        la $a0, goAgainInput    #ask the user if they want to go again. 
        syscall
        lb $t0, ($a0)
        beq $t0, 121, goAgain
        j exit

exit:
    la $a0, exitMessage
    li $v0, 4   #print exit message and get outa' here. 
    syscall
    li $v0, 10
    syscall

goAgain:
    la $a0, userInput
    li $t9, 100
    loopReset:
        beqz $t9, main  #erase all junk still in the memory from last main call, then return to main. 
        addi $t9, $t9, -1
        sb $zero, ($a0)
        addi $a0, $a0, 1
        j loopReset

再次感谢。

【讨论】:

  • #decrement from end of $t1, increment from beginning of $t4 之类的评论几乎毫无用处。我们已经可以看到指令递减$t1。有用的评论会为寄存器中的内容使用描述性名称,或者说类似"scan the string forwards with t4, backwards with t1"
猜你喜欢
  • 2017-03-28
  • 1970-01-01
  • 2013-08-05
  • 2018-08-10
  • 1970-01-01
  • 2020-05-07
  • 1970-01-01
  • 2015-09-08
  • 2010-12-17
相关资源
最近更新 更多