Christian Peterson
Christian Peterson

Reputation: 33

Converting C code to MIPS - Iterative Factorial Function

I'm pretty new to programming, only a few months in and was just fiddling around with some Assembly code. I ran into a problem with my MIPS code and I narrowed the problem down to my loop after printing the value of each variable. It only prints 1 as the result of any integer input. Essentially I am trying to convert this:

int fac(int k) {
    int i, f = 1;
    for (i = 1; i <= k; i++) {
        f = f * i;
    }
    return f;
}

To this:

fac:
    move $t4, $t0 #$t0 is the input from the user and $t4 is k in the C code
    li $t1, 1 #$t1 is f in the C code, initialising it to 1
    li $t2, 1 #$t2 is i in the C code, declaring it as 1
    loop:
    ble $t2, $t4, end_loop #i<=k, end the loop
    mul $t1, $t1, $t2 #f=f*i
    addi $t2, $t2, 1
    j loop
    end_loop:

I tested the code by putting in a bunch of print statements and was able to get $t4 and $t0, as the input but both $t1, and $t2 remain as 1 after the loop. Do I have to jump into the loop?

Upvotes: 1

Views: 1510

Answers (2)

Andre Kampling
Andre Kampling

Reputation: 5631

Your loop condition with ble $t2, $t4, end_loop #i<=k, end the loop will end the loop if i<=k but instead you want to run it as long as this condition meats. Your loop implementation doesn't even enter the loop for factorial inputs greater 1.

Edit: As said in the comments with the following code I've implemented a do {...} while (); loop which is not what the OP has asked for. However the code would work. Below the stroked text the real answer (for loop implementation) follows.

Remove the end_loop: label and jump to the loop: label with ble as last statement instead:

fac:
    move $t4, $t0 #$t0 is the input from the user and $t4 is k in the C code
    li $t1, 1 #$t1 is f in the C code, initialising it to 1
    li $t2, 1 #$t2 is i in the C code, declaring it as 1
    loop:
    mul $t1, $t1, $t2 #f=f*i
    addi $t2, $t2, 1
    ble $t2, $t4, loop #i<=k, loop goes on if not this doesn't jump

To implement the for loop you've asked for you need to change the ble (<=):

ble $t2, $t4, end_loop #i<=k, end the loop

to bgt (>):

bgt $t2, $t4, end_loop #i>k, end the loop

Upvotes: 0

paxdiablo
paxdiablo

Reputation: 881653

ble $t2, $t4, end_loop #i<=k, end the loop

No, the second part of a C for statement is the condition for which you want to continue the loop, not end it.

What you are doing here is not even entering the body of the loop, which is why $t1 and $t2 stay the same value as you initialised them to.

You probably want to use bgt rather than ble.

Upvotes: 2

Related Questions