Palindromic是一个可以双向阅读的字符串。比如“雷达”,“哇”等。
从C我们知道我们可以使用“for”循环和“if”表达式检查给定字符串:
for(i=0; i<length; i++)
if(str[i] == str[length-i-1])
printf("Palindromic");
else
print("Non Palindromic");
这样我们就可以通过双方到达弦乐的中心。
此代码要求我们对字符进行计数以了解字符串的长度。
在MIPS上,这个“for”循环似乎相当复杂。
这是我自己的地方:
.data
str: .space 20
isntpal: .asciiz "it is not palindromic!"
ispal: .asciiz "it is palindromic!"
.text
.globl main
main:
add $t0, $zero, $zero #t0 = i counter for the loops
add $t1, $zero, $zero #t1 = j counter for length of the string
li $v0, 8 #gets(str)
la $a0, str
la $a1, 20
syscall
length:
lb $s0, str($t0) #load each character to s0
beq $s0, '\0', NEXTCHECK
add $t0, $t0, 1 #i++ to scan all the characters of the string
add $t1, $t1, 1 #j++ for the total length of the string
j length
NEXTCHECK:
add $t0, $zero, $zero #clean the t0 register from the length loop
pal:
sub $t4, $t1, $t0 #length - i - 1
sub $t4, $t4, 1
lb $s0, str($t0) #str[i]
lb $s1, str($t4) #str[length-i-1]
slt $t3, $t0, $t1 #for(i=0; i<length; i++)
beq $t3, $zero, EXIT
add $t0, $t0, 1 #i++
beq $s0, $s1, ELSE #if (str[i] == str[length-i-1])
li $v0, 4 #printf("It is palindromic");
la $a0, ispal
syscall
j EXIT
ELSE:
li $v0, 4 #else printf("It is not palindromic");
la $a0, isntpal
syscall
j EXIT
j pal
EXIT:
li $v0, 10
syscall
我有一个问题,我应该知道我应该有EXIT和ELSE标签,我认为这就是为什么它总是返回字符串是回文的,即使它不是。
放置标签的正确方法是什么?
是否需要多个标签?
答案 0 :(得分:0)
正确有效的C版本:
bool is_palindrome(const char * str, const size_t length) {
const char * frontptr = str; // front pointer: points at the very first character of string
const char * backptr = str + length-1; // back pointer: points at the very last character of string
while (frontptr < backptr) { // while front pointer points ahead of back pointer
if (*frontptr != *backptr) return false; // characters differ => not a palindrome
++frontptr; // move front pointer at next character in string
--backptr; // move back pointer at "next" character toward start of string
}
// front pointer points at/beyond back pointer
// all chars were compared (except middle one for odd length string, which is "palindromic" always)
// and all were equal, thus the input string is a palindrome, if this point is reached
return true;
}
这个C代码是故意编写的,这样可以非常简单地转换为ASM(例如每条C行1-2条指令)。
如果你知道它的地址(C中的指针),如何从内存中加载一个值:
la $a0,some_address # a0 = address (pointer)
lb $t0,($a0) # t0 = byte loaded from memory at a0
如何在ASM中递增/递减指针:将指针所指向的元素大小添加到指针的当前值。
使用ASCII字符串时,元素是单字节,因此要向前/向后移动一个字符,必须在指针上添加+ 1 / -1,如:
addi $a0,$a0,1 # ++byte_ptr
addi $a1,$a1,-1 # --byte_ptr
如果您使用单词数组,您可能需要执行+ -4将指针向前/向后移动一个元素。
并学习如何使用"procedures" in MIPS ASM,这样你就可以创建一些通用的通用“获取字符串长度”代码,然后通过简单的复制/粘贴重新使用它(除非你最终创建自己的一些库) )。
如果您遵循C ++示例,也可以作为单独的程序进行回文测试。
在主要内容中,您可以使用更简单的代码来维护+调试+原因:
# input string
# prepare arguments for get_length
# call get_length
# process result and prepare arguments for is_palindrome
# call is_palindrome
# set a0 to one of the two result strings based on return value
# display string
# exit
指令总数可能会稍微长一点,因为您将有额外的jal
和jr $ra
行,但它可以让您在编写/调试时专注于更短更简单的代码部分