Logan
Logan

Reputation: 1117

Converting C code to MIPS (Assembly Source Code)

I have the task of converting this code into assembly:

int prodArray (int A[], int n) {
   if (!n)
        return 1;
   else if (n == 1)
        return A[0];
   int mid = n / 2;
   int left = prodArray(A, mid);
   int right = prodArray(A + mid, n - mid);
   return left * right;
}

Here is what I have so far, and note that loop, loop2, and loop3 are pretty much the same:

main:
    add $t0, $0, $0         # Initialize t0
    add $t1, $0, $0         # Initialize t1
    addi $t4, $0, 1         # Make t2 equal to 1

# Main Loop
loop:
    beq $a1, $t2, exit      # If the second argument is 0 branch to exit
    beq $a1, $0, exit2      # If the second argument is 1 branch to exit2
    srl $t2, $a1, 1         # Divide n by 2
    sll $t3, $a1, 1         # Multiply n by 2
    add $a1, $t2, $0        # make n half
    b loop2                 # branch to loop

loop2:
    beq $a1, $t2, exit
    beq $a1, $0, exit2
    srl $t2, $a1, 1
    sll $t3, $a1, 1
    add $a0, $a0, $t2       # Make a0 point to A + mid
    b loop3

loop3:
    beq $a1, $t2, exit
    beq $a1, $0, exit2
    srl $t2, $a1, 1
    sll $t3, $a1, 1
    add $a1, $t2, $0
    b loop

# exit
exit:
    ja $ra, $t4

exit2:
    ja $ra, 0(a1)

I'm not very good at assembly and need any assistance I can get. Note that a0 is meant to be the first argument and a1 is meant to be the second argument.

Thanks for any guidance you're able to give!

Upvotes: 0

Views: 1139

Answers (2)

user149341
user149341

Reputation:

Here's a few pointers…

  1. There aren't any loops in the C code you're starting with, so there shouldn't be any loops in your assembly either. This function does call itself, but that should be implemented just like any other subroutine call (i.e, using jal), not by trying to inline the function into itself. (Indeed, you can't inline this subroutine without some rather major refactoring.)

    Remember to save any registers on the stack that you'll need to restore after the subroutine call, including the original arguments in $v0 and $v1, and the return address $ra.

  2. There is no ja instruction. The correct instruction to use at the end of a subroutine is jr $ra, and you need to put the return value in $v0 before executing that.

  3. Don't forget about branch delay slots! I see a number of places where an instruction may end up executing that you didn't want; you may want to just stick a nop after every conditional branch for now.

Upvotes: 0

JoelFan
JoelFan

Reputation: 38704

If you have the gcc compiler, use, the -S switch, for example: gcc -S helloworld.c . This will produce a .s file with the assembly code. This question has more info: How do you get assembler output from C/C++ source in gcc?

Upvotes: 1

Related Questions