简体   繁体   中英

Why isn't my reversing MIPS code working correctly?

I have recently asked a question regarding MIPS since I have difficulties understanding it especially when it comes to pointers.

My objective is to make a function that takes 2 pointers, one points to the beginning of a String and the second points to it's end ( more specifically when we detect a "." ). Then we start reversing the String.

For example : This is good. Pointer 1 points to the beginning of the String, pointer 2 points to String.length -1 "."

Then we start swapping The first char with the last one until we reverse all the String so we have an output like this .doog si sihT

UPDATE : Now the function below works well

Input University Output : ytisrevinU

Now I want to make a small modification so that when we read a long text separated by ".", we reverse each sentence without changing the order.

Input : Canada is colder than America. America is colder than Europe.

(Using our function we will get ) : .eporuE naht redloc si aciremA .aciremA naht redloc si adanaC

WHAT I WANT TO HAVE : .aciremA naht redloc si adanaC. eporuE naht redloc si aciremA

 # Program to reverse a string input by the user
 .data
 array: .space 128
 input: .asciiz "Enter a string: "
 size: .word 128

.text

 j main


length:
# return length of the input string
# $a0 - address of string
# $v0 - length of the string
add $v0, $0,$0 # set $v0 to 0
loop:
lb  $t0, 0($a0)     #load byte
beqz $t0, fin   #if null
addi $v0, $v0, 1    #increase the length
addi $a0, $a0, 1    #next
j loop      #recursive call
fin:
subi $v0,$v0,1
jr $ra      #return

reverse:
blt $a1, $a0, reverse_end
lb $t0, ($a0)
lb $t1, ($a1)
sb $t0, ($a1)
sb $t1, ($a0)
addi $a0, $a0, 1
addi $a1, $a1, -1
b reverse

reverse_end:
li $v0, 0
jr $ra

main:
addi $s0, $0, 128
addi $t0, $0, 0

la $a0, input   #service call to add the input String @
li $v0, 4       #affichage
syscall
# read string from the user into $a0
la $a0, array
lw $a1, size
li $v0, 8
syscall
jal length# $v0 contains length of string

# reverse the string
la $a0, array       #Lire le string
move $a1, $v0       # Put in a1 the length's result
add $a1, $a0, $v0   # pointer to the last character
jal reverse

# print the reverse string
la $a0, array
li $v0, 4
syscall 

so when we detect a ".", we call reverse, then we continue with the sentence after the "." detected, until we find another ".", call reverse.

Thanks

Problem: Your reverse function relies on the fact that $a0 will have the address of the first character and $a1 will have the address of the last character.

But there is no where you are updating $a1 to point to the end of the string.

Your 7th line from bottom:

# add $a0, $a0, $a1

is equivalent to $a0 = $a0 + $a1. Since $a1 = length and $a0 = beginning address of the string, after execution of the above line, $a1 is still the length and $a0 is the end of the string.

Now when your reverse function kicks in, it checks the value of $a0 and $a1 and compares.

Guess what it finds! $a0 has some address ( beginning of the string or end of the string depending on whether or not you comment the line out or not ) but $a1 is always less than 128 (since it is the length of the string) . It learns that $a1 < $a0 and ends the method right away.

Fix: What you need is to say:

(address of last character = address of first character + length of the string)

In other words, $a1 = $a0 + $v0, MIPS command for that would be:

add $a1, $a0, $v0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM