- #1
SpiffyEh
- 194
- 0
Homework Statement
The goal here is to write some MIPS functions to solve a common technical interview
question: how can you reverse the order of the words in a string? For example, reversing
the words in the string I Love Lucy would result in Lucy Love I.
A string is just an array of bytes, with each byte representing one character. The last byte
of the array is always 0, to indicate the end of the string. Also, a space is represented by
the value 32.
First write a function rev, which simply reverses bytes in an array. The arguments
passed in $a0 and $a1 are the starting address and the number of bytes to reverse.
Using the rev function, you should now be able to write revwords to reverse the
order of the words within a string.
You can implement revwords according to the following basic algorithm.
1. Call rev to completely reverse the original string. For example, I Love Lucy becomes
ycuLevoLI. Remember that strings are terminated by a 0 byte.
2. Then use rev to reverse each word in the new string—ycuLevoLI becomes Lucy Love I.
You can assume that “words” are separated by a space character, with the byte value 32.
The Attempt at a Solution
revwords isn't a function in my attempt, i put it in main for now until i get it working. I created the rev function and tested it and it works for a string. Then i went on to create the other one and that's where I'm having issues. It goes through the words and everything but the output i get is LucyLove_I_ whrere _ are spaces. I've tried to fix it where the space is still in the correct location but I cannot figure it out. The code is posted below, if anyone has any suggestions it would really help, I've spent hours trying to fix this little bug and I've lost hope.
.data
string: .asciiz "I Love Lucy"
endl: .asciiz "\n"
space: .asciiz " "
.text
.globl main
rev:
#la $s0, string
#addi $a1, $0, 7
add $t2, $0, $0 # set the counter variable to 0
srl $t0, $a1, 1 # divide the number of characters by 2
add $t1, $0, $a1 # put the number of characters into t1
addi $t1, $t1, -1 # subtract 1 from the number of characters
add $t1, $a0, $t1 # add to the beginning address to get to the end address
loop:
lb $t6, 0($a0) # load the byte into t6 (left half)
lb $t7, 0($t1) # load the byte into $t7 (right half)
sb $t6, 0($t1) # store t6 at position t1, basically swap
sb $t7, 0($a0) # store t7 at position a0, swapping
addi $a0, $a0, 1 # get the address of the next pixel by adding 1
addi $t1, $t1, -1 # get the address of the previous pixel from end by adding -1
addi $t2,$t2, 1 # increment the counter by 1
bne $t0, $t2, loop # while the counter is not equal to half the number of characters loop
jr $ra # jump back to where the function was called
main:
la $a0, string # load the address of the string into a0
addi $sp, $sp, -12 # make space on the stack for a0
sw $a0, 0($sp) # store a0
sw $ra, 4($sp) # store ra
addi $a1, $0, 11 # 11 = total number of characters
jal rev # call rev with whole string
la $a0, string # print the string and an end line
li $v0, 4
syscall
la $a0, endl
syscall
lw $a0, 0($sp) # load the string back into a0, since rev changed the variable
addi $t3, $0, 32 # t3 holds the value for a space, 32
add $s0, $a0, $0 # s0 is a0
outerLoop:
add $a1, $0, $0 # set the num of characters counter to 0
add $a0, $s0, $0 # set a0 to s0
innerLoop:
addi $a0, $a0, 1 # add 1 to the current address
addi $a1, $a1, 1 # add 1 to the counter
lb $t8, 0($a0) # load the byte at a0
beq $t8, $0, after # if it is the end jump to after
bne $t8, $t3, innerLoop # if there is not a space loop again
after:
add $s0, $a0, $0 # add a0 to s0 for storage
sub $a0, $a0, $a1 # subtract a1 from a0 to get to the beginning of the word
jal rev
add $a0, $s0, $0 # restore a0 after function call
lb $t8, 0($a0) # load the byte into t0
bne $t8, $0, outerLoop # if its not the end loop again
la $a0, string
li $v0, 4
syscall