【发布时间】:2015-04-17 15:44:02
【问题描述】:
我正在参加一个计算机组织课程,该课程通过 MIPS 汇编教授计算机的低级功能。作业中的一个问题是回文检查器。这里是:
编写一个 MIPS 函数(称为“回文”),如果 输入字符串是回文,否则返回 0。的地址 字符串将在 $a0 中传递,值应返回 $v0。这里一个字符串是一个回文,如果它向前读相同或 向后方向(包括空格、标点符号等 on,但不区分大小写(即“A”和“a”被认为是 相同))。请注意,字符串以“\0”(C/C++ 约定)结尾。你 需要使用“test_palindrome.s”测试你的程序
我写了一个简单的c++程序来解决这个问题,包括一个基本的tolower函数。然后我手动将其翻译成 mips。我已经让它运行了,但是用我的 c++ 程序对照 mips 程序检查回文测试字符串,我没有得到相同的结果。
为了测试 mips 功能,我使用了教授提供的程序。它说它们都不是回文。这是 MIPS 代码,有一个注释部分显示了我原来的 c++ 代码。
# Program to test if a palindrome function works properly or not
# Written by Xiuwen Liu for CDA 3100 - Homework #3, problem #2
# Register usage
# $s7 - save $ra
# $s2 - current address of the string to be tested
# $s3 - the next of the last string to be tested
# $a0 - for function parameter / syscall parameter
# $v0 - syscall number / function return value
.text
.globl main
main:
addu $s7, $ra, $zero, # Save the ra
la $s2, test_str # Load the starting address of the array
la $s3, is_pali_msg, # the next of last address
pali_test_loop:
lw $a0, 0($s2) # $a0 is the address of the string
li $v0, 4 # system call to print a string
syscall # print string
li $v0, 4 # print a new line
la $a0, newline
li $v0, 4
syscall
lw $a0, 0($s2) # $a0 is the address of the string
jal palindrome # call palindrome
beq $v0, $zero, pali_no #if $v0 is 0, it is not a palindrome
li $v0, 4 #it is a palindrome
la $a0, is_pali_msg
syscall
j pali_test_end
pali_no: #it is not a palindrome
li $v0, 4
la $a0, not_pali_msg
syscall
pali_test_end:
li $v0, 4
la $a0, newline
syscall
addiu $s2, $s2, 4
lw $a0, 0($s2)
beq $a0, $s3, pali_done
j pali_test_loop
pali_done:
li $v0, 10
syscall
addu $ra, $zero, $s7 #restore $ra since the function calles
#another function
jr $ra
add $zero, $zero, $zero
add $zero, $zero, $zero
########## End of main function #########
这是我的代码:
# My working c++ code
# int arrayLen ( char s[]) {
# int counter = 0;
# while(s[counter] != '\0'){
# if (s[counter] > 64 && s[counter] < 91)
# s[counter] = s[counter] + 32;
# counter++;
# }
# return counter;
# }
#
# int palindrom(char s[]){
# int i;
# int l = arrayLen(s);
# for(i=0;i<=l/2;i++)
# if(s[i]!=s[l-i-1]) return 0;
# return 1;
# }
palindrome:
addu $s4, $ra, $zero # save $ra
jal arrayLen # get string length and set to lowercase
move $t0, $zero # i = 0
move $t1, $v1 # l = arrayLen(s)
srl $t2, $t1, 1 # divide l by 2
palinFor:
bgt $t0, $t2, palinForExit # end for loop when i > l/2
sub $t3, $t1, $t0 # l - i
addi $t3, $t3, -1 # l - i - 1
add $t4, $a0, $t0 # s[i]
add $t5, $a0, $t3 # s[l-i-1]
addi $t0, $t0, 1 # i++
lbu $t4, ($t4) # load s[i]
lbu $t5, ($t5) # load s[l-i-1]
sne $t6, $t4, $t5 # if not equal, set $t6 to 1
beq $t6, 1, palinForExit # leave loop if not equal
j palinFor # loop again
palinForExit:
sne $v0, $t6, $zero # set return value: 0 for not palindrome, 1 for palindrome
addu $ra, $zero, $s4 # restore $ra
jr $ra # return to function caller
arrayLen:
li $t0, 0 # counter = 0
sll $t1, $t0, 2 # counter * 4
add $t1, $t1, $a0 # address of s[counter] in $t1
lbu $t2, ($t1) # load s[counter]
while:
beq $t2, 0, whileEnd # skip to end of while loop if s[counter] == \0
blt $t2, 64, breakIf # skip if not uppercase range
bgt $t2, 91, breakIf # skip if not uppercase range
addi $t2, $t2, 32 # add 32 to make character lowercase
sw $t2, ($t1) # save change to memory
breakIf:
addi $t0, $t0, 1 # counter++
whileEnd:
move $v1, $t0 # return value of arrayLen is counter
jr $ra # return to function caller
这是我的代码停止的地方,测试代码的 .data 部分如下:
.data
#The following examples were copied from
# http://en.wikipedia.org/wiki/Palindrome
pali1:
.asciiz "Socorram me subi no on ibus em Marrocos" #Brazilian Portuguese
pali2:
.asciiz "Ein Neger mit Gazelle zagtim Regen nie" #German
pali3:
.asciiz "stressed desserts"
pali4:
.asciiz "palindromes"
pali5:
.asciiz "tattarrattat"
is_pali_msg:
.asciiz " The string is a palindrome."
not_pali_msg:
.asciiz " The string is not a palindrome."
newline:
.asciiz "\n"
test_str:
.word pali1, pali2, pali3, pali4, pali5, is_pali_msg
学习这些东西我的大脑很疼。一些关于为什么它不起作用的方向将不胜感激,谢谢:D
【问题讨论】:
标签: mips