使用 mips 组件检查回文

问题描述

.data

org_str: .space 256
rev_str: .space 256
str: .asciiz "Enter the Line: "
pal: .asciiz "palindrome"
not_pali: .asciiz "Not palindrome"

.text 
.globl main
main:
    
    
    li $v0,4
    la $a0,str
    syscall
    
    # Taking String from the user
    li $v0,8
    la $a0,org_str
    li $a1,256
    syscall
    
    # Initilize $t0 and $t2
    li  $t0,0
    li  $t1,0
    
loop_len:
    add $t1,$a0,$t0
    lb  $t2,0($t1) # Load the data in the byte in $t2
    beqz    $t2,len_exit   # Loop till $t2 reaches zero
    addiu   $t0,$t0,1 # increment of the counter
    j   loop_len
len_exit:

    #Return $t0 to the last Charater
    subi $t0,1
    li $s0,0   # Initialize variable
    addi $s0,0    # Save the length of the String
    
    # Load the original string in $t2
    la $t2,org_str
    
    # Intialize i and j
    li $t1,0   # i 
    li $t3,0   # j
    
reverse_loop:
    add $t3,$t2,$t0   # $t2 is the base address
    lb $t4,0($t3)      # load a byte
    beqz $t4,exit      # go to the exit if null was found
    sb $t4,rev_str($t1)    # Overwrite the byte
    addi $t0,-1   # decrement of j by 1 (j--)
    addi $t1,$t1,1    # increment of i by one (i++)
    j reverse_loop      # Loop until we reach the length of the String
exit:
    
    li $t0,0
    li $t4,0
    li $t7,0
    
CheckChar_loop:
    
    lb $t4,org_str($t0)
    lb $t7,rev_str($t0)
    
    beq $t4,$zero,exit_1  # go to the exit if null was found
    bne $t4,$t7,not_pal   # if $t7 and $t4 not equal
    addi $t0,1    # increment of i by 1 (i++)
    j CheckChar_loop
exit_1:

    #li $v0,1
    #addi $a0,0
    #syscall

    li $v0,pal
    syscall

    #Exit the program
    li $v0,10
    syscall
    
not_pal:
    
    #li $v0,0
    #syscall
    
    li $v0,not_pali
    syscall
    
    
    #Exit the program
    li $v0,10
    syscall
    
.end main

我正在尝试检查回文。因此,我们的想法是反转字符串并在每个索引处检查反转字符串中的字符是否与原始字符串相同。 我试图检查 org_str 是否等于 rev_str 但它每次都以 $t7 和 $t4 的形式存在,即使它们相等。 rev_str 是 org_str 的反转字符串。

解决方法

基本调试技巧

任何编写汇编语言的人都应该能够单步执行并观察/验证他们的代码执行。

单步执行并验证每条指令是否符合您的预期。大多数指令都有一个主要作用:改变寄存器的值,或改变内存的值。并且所有指令都告诉处理器接下来要运行什么指令。所以,我们需要验证主效果和控制流程(接下来是什么指令)。 (syscall 可以更改多个内存位置并提供返回结果。)

在调试从未经过测试的新代码时,请使用尽可能小的输入来简化调试。

例如,测试输入“A”(0x41)。 (从技术上讲,最小的输入是空字符串,最好也测试一下。)

随着程序的发展,使用断点跳过您已经知道正在运行的代码,然后从那里单步执行新代码。


在你的程序中,你应该已经注意到副本的第一个字节是错误的,甚至在它存储到内存之前,你可以通过单步执行大约 35 条指令来看到这一点。


  1. 你有一个经典的错误,这是由读取字符串系统调用附加到用户输入文本的换行符引起的。在读取字符串系统调用后检查 org_str 的内存,您应该已经看到了这一点。这个换行符会在代码中的两个地方引起一个差错——在复制循环和 pal 检查循环。您可以使循环基于计数,也可以使用空字节粉碎换行符以缩短该字符的输入。

  2. 您计算字符数,然后向后复制字符,但错误地依赖 org_str 之前的空字节来停止复制循环。

    我们只使用空终止字符串,不应期望字符串以空开始和以空终止——除非明确提供了空初学者(在您的情况下不是这样)。一般来说,在处理字符串(作为参数传递,由其他代码创建)时,我们不能依赖于能够轻松提供空初学者,因此最好的编程实践是在计数(递减一个)时结束复制循环) 达到零。 (在这里很容易被一个人关闭,所以也用空字符串进行测试(即应该构造为 while 循环,而不是重复直到。))

  3. 停止将寄存器初始化为零,然后再设置一些其他值。你做的相当于

    int s0 = 0;   // <--- this initialization is pointless 
    s0 = t0 - 1;  // since s0 is immediately repurposed with a new value here

顺便说一句,您从不使用 s0,因此即使将其设置为 t0-1 也不会被使用,但是当您修复代码的一对一错误时,情况可能会发生变化。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...