0
votes

My project is to convert the below code, which reverses the order of a string i.e.( string --> gnirts). I have no understanding of how to start the translation into MIPS assembly. Any help or clarification on how to do this project would be greatly appreciated.Even just a similar example would be awesome.

#include <iostream>
using namespace std;

void reverse(char [], int size);
void swap(char *x, char *y);

int main() 
{

char array[] = "0123456789";
cout << array << endl;
reverse(array, 10);
cout << "Reverse:" << endl;
cout << array << endl;
return 0;

}


//Takes in a character array and the size of set array and loops through 
until 
you reach a middle point
void reverse(char array[], int size) 
{
int j=size-1;
for(int i=0; i<j; i++) 
{
    swap(&array[i], &array[j]); //swaps the first and last element by 
passing the memory locations
    j--;
}
}

//Takes pointers to the closer element and swaps it into the farther element
void swap(char *x, char *y) 
{
char temp = *x; //first element stored in temp
*x = *y; //last element sored in first
*y = temp; // temp stored in last
 }
1
You need somebody who knows MIPS assembly. Or use C compiler, if you have working valid C.Ped7g

1 Answers

2
votes

Here are the reverse and swap functions. You'll need to add the main that sets up things and prints:

# reverse -- reverse elements of a byte array
#
# arguments:
#   a0 -- pointer to array
#   a1 -- length of array (bytes)
#
# temporary:
#   a1 -- pointer to last char
#   t0 -- return address
reverse:
    move    $t0,$ra                 # save return address

    addu    $a1,$a0,$a1             # point past the array (&array[SIZE])
    addiu   $a1,$a1,-1              # point to last element of array
    j       reverse_next            # start loop

reverse_loop:
    jal     swap
    addiu   $a0,$a0,1               # move LHS pointer higher
    addiu   $a1,$a1,-1              # move RHS pointer lower

reverse_next:
    blt     $a0,$a1,reverse_loop    # more to do? loop if yes
    jr      $t0                     # return

# swap -- swap elements of a byte array
#
# arguments:
#   a0 -- pointer to LHS of array
#   a1 -- pointer to RHS of array
#
# temporary:
#   v0 -- LHS char
#   v1 -- RHS char
swap:
    lb      $v0,0($a0)              # get LHS byte
    lb      $v1,0($a1)              # get RHS byte

    sb      $v1,0($a0)              # store LHS byte
    sb      $v0,0($a1)              # store RHS byte

    jr      $ra                     # return

UPDATE:

See my comment on your other page about your runtime exception (e.g. you're passing indexes to swap instead of pointers).

Here, I had recoded the reverse function to use pointers. This is the C equivalent:

void
reverse(char *array, int size)
{
    char *endp;

    // this could be "endp = &array[size - 1]" but this is closer to the
    // assembly
    endp = &array[size];
    endp -= 1;

    for (;  array < endp;  ++array, --endp)
        swap(array,endp);
}

UPDATE #2:

Spoiler Alert: This is the complete program ...

    .data
prompt:     .asciiz     "Enter string to reverse: "
string:     .space      1000

    .text
    .globl  main
main:
    li      $v0,4                   # print syscall
    la      $a0,prompt
    syscall

    li      $v0,8                   # read string
    la      $a0,string
    li      $a1,1000
    syscall

    la      $a0,string
    jal     strlen                  # get string length

    move    $a1,$v0                 # save string length
    la      $a0,string
    jal     reverse

    li      $v0,4                   # print string
    la      $a0,string
    syscall

    li      $v0,10                  # exit
    syscall

# reverse -- reverse elements of a byte array
#
# arguments:
#   a0 -- pointer to array
#   a1 -- length of array (bytes)
#
# temporary:
#   a1 -- pointer to last char
#   t0 -- return address
reverse:
    move    $t0,$ra                 # save return address

    addu    $a1,$a0,$a1             # point past the array (&array[SIZE])
    addiu   $a1,$a1,-1              # point to last element of array
    j       reverse_next            # start loop

reverse_loop:
    jal     swap
    addiu   $a0,$a0,1               # move LHS pointer higher
    addiu   $a1,$a1,-1              # move RHS pointer lower

reverse_next:
    ble     $a0,$a1,reverse_loop    # more to do? loop if yes
    jr      $t0                     # return

# swap -- swap elements of a byte array
#
# arguments:
#   a0 -- pointer to LHS of array
#   a1 -- pointer to RHS of array
#
# temporary:
#   v0 -- LHS char
#   v1 -- RHS char
swap:
    lb      $v0,0($a0)              # get LHS byte
    lb      $v1,0($a1)              # get RHS byte

    sb      $v1,0($a0)              # store LHS byte
    sb      $v0,0($a1)              # store RHS byte

    jr      $ra                     # return

# strlen -- get string length
# RETURNS:
#   v0 -- string length
#
# arguments:
#   a0 -- pointer to string
#
# clobbers:
#   t1 -- current char
strlen:
    move    $v0,$a0                 # remember base address

strlen_loop:
    lb      $t1,0($a0)              # get the current char
    addi    $a0,$a0,1               # pre-increment to next byte of string
    bnez    $t1,strlen_loop         # is char 0? if no, loop

    subu    $v0,$a0,$v0             # get length + 1
    subi    $v0,$v0,1               # get length (compensate for pre-increment)
    jr      $ra                     # return