0
votes

As is obvious from my question history today, I am working on a MIPS project that will reverse a string, in this case "Hello, World". I think I have my loop and string reversal functions correct, but I cannot figure out the swap function itself, or how to output the manipulated string.

I know that the basic swap for something like this would be:

sll $t1, $a1, 2
add $t1, $a0,$t1
lb $t0,0($t1)
lb $t2, 4($t1)

sb $t0,0($t1)
sb $t2, 4($t1)
jr $ra

But I have no idea what that does or how I interpret that to fit my code. If some holy saint out there could explain how that works and how syscalls work I would be eternally grateful. My code below:

.data 

    string: .asciiz "Hello, World!"

.text
main:
    li $v0, 4
    la $a0, string #store string in a0
    syscall



    jal stringreverse

stringreverse:
    add $t0,$a0,$zero   #base address of string
    add $a1, $zero,14   #stores size of string in a1
    addi $t2, $a1, -1   #j = length -1
    add $t3,$zero,$zero     #i = 0

loop:
    jal swap
    addi $t2,$t2,-1     #j--
    addi $t3,$t3,+1     #i++

    slt  $t7,$t3,$t2 #set t7 to 1 when j is less than i
    bne  $t7,$zero,loop # if i is greater than j, keep looping
    j done
swap:   #swaps the sooner element with the later and returns back to the loop
    lb      $v0,0($t3)              # updated to fit my registers t3 =i
    lb      $v1,0($t2)              # updated to fit my registers t2 =j

    sb      $v1,0($t3)              
    sb      $v0,0($t2)              

    jr $ra

done:
    .....procedure here.....
    syscall 
1
See my answer to your previous question: stackoverflow.com/questions/49393986/… BTW, you should really just edit the original rather than posting a [slightly modified] duplicateCraig Estey
The reverse is similar in structure to mine. In my reverse/swap, I use char* pointers throughout (vs. index variables). Notice that main -> reverse -> swap, so the $ra value from main needs to be preserved by reverse because the jal swap clobbers itCraig Estey
Also, notice that from the mips ABI, only $s0-$s7 must be preserved (and the stack register must, at function exit, point to the same place it was a function entry). Otherwise, any reg can be used for any purpose. I deliberately through in the curveball of using $v0/$v1 in my swap (vs. $t*). The only truly hardwired [by the architecture] regs are $ra and $zeroCraig Estey
I appreciate the advice, I didn't know the etiquette. As for your second comment, can you elaborate? I am working off of examples and do not have much knowledge as to the actual workings of the procedures. So im not really sure what you mean about the $ra value.djjeane
When you do jal func, it puts the return address (the address after the jal into the $ra (return address) register) and then jumps to func. The use of $ra by jal is one of the few hardwired choices. The usual way to return is jr $ra which is jump to address in $ra. This is the normal sequence, but jr is not tied to $ra, you can use any other reg (e.g. in my code, I used $t0 to illustrate this: jr $t0 because I saved $ra into $t0 earlier)Craig Estey

1 Answers

0
votes

It looks like you're treating the lb (load byte instruction) like a la (load address instruction).

You probably want to do something more like this:

swap:
    lb    $temp1,   str($t2)    #load temp1 address with byte at $t2 in str 
    lb    $temp2,   str($t1)    #load temp2 address with byte at $t1 in str
    sb    $temp2,   str($t2)    #store temp2 byte into $t2'th position in str
    sb    $temp1,   str($t1)    #store temp1 byte into $t1'th position in str
    jr    $ra

with some data like:

.data
str:
    .asciiz "your string here"

Hopefully this clears things up a bit for you.