Assembly 测试字符串是否为回文的代码-MIPS

Assembly 测试字符串是否为回文的代码-MIPS,assembly,mips,palindrome,Assembly,Mips,Palindrome,我正在尝试用MIPS编写一个程序,确定字符串是否为回文。程序应该忽略用户输入字符串中的所有标点和空格。以下字符串将被视为我的程序的回文 “12321” “夫人,我是亚当。” “去挂一条意大利腊肠吧:我是一只烤宽面条猪!!!” 我不明白为什么我的程序不起作用。我对mips还很陌生,因为它可能是我忽略或完全错误的简单事情。这是我的密码: .data charCount: .byte 0 goAgain: .asciiz "" userInput: .asciiz "" .text main:

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

  • “12321”
  • “夫人,我是亚当。”
  • “去挂一条意大利腊肠吧:我是一只烤宽面条猪!!!”
  • 我不明白为什么我的程序不起作用。我对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:
    

    这就是我提出的答案。我重新启动了它,这样我就可以用一个清晰的头脑开始并完成它。这次也有很多评论。享受。谢谢你的所有意见,以帮助

    .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
    

    再次感谢

    程序集使用通用寄存器名而不是变量名,因此注释和有意义的标签对于使代码可读性至关重要。为什么要在下一步减去2:?在z字节上备份不是应该是1吗?在eval:beq$t2,$t3,如果字符串是偶数个字符,那么equal永远不会是真的。它应该测试t2>=t3。下一步测试2:您需要测试字符串末尾的a2>=a0。在nextT3:您需要测试a0CORRECTION:是否忽略关于beq$t2,$t3的注释。我的意思是:在eval:beq$a0,$a2时,isPali应该测试a2>=a0。类似于
    #从$t1末尾递减,从$t4开头递增的注释几乎是无用的。我们已经可以看到指令递减
    $t1
    。一个有用的注释将使用一个描述性名称来表示寄存器中的内容,或者说类似于
    “用t4向前扫描字符串,用t1向后扫描字符串”