I'm trying to convert a C Code to MIPS code.
int main() {
int a;
int b;
int result = 0;
if (a != b)
result = test(a, b);
else
result = a + b;
return result;
}
int test(int a, int b) {
if (a > b)
return multiply(a, b)
else
return subtract(a, b)
}
int multiply(int a, int b) {
return a * b;
}
int subtract(int a, int b) {
return a - b;
}
This code contains nested function calls inside test function. I have put the return address of test function into stack and trying to return the subtracted or multiplied value to the main.
But in my case, my code executes both subtract and multiply functions. I'm trying to put my result to s0. After running s0 always shows subtraction of values. If I put multiply result to s1, s1 shows true value.
I think subtract function overrides value at s0. But when case is multiply, why subtract method is called? I have an if/else block, but this part seems to be not working.
Here is my MIPS Code, what am I doing wrong?
.data
numberA: .word 4
numberB: .word 2
.text
.globl main
main:
addi $s0, $0, 0 # result = 0
lw $a0, numberA
lw $a1, numberB
bne $a0, $a1, L1
add $s0, $a0, $a1
L1: jal test
add $s0, $v0, $0
li $v0,10
syscall
test:
addi $sp, $sp, -4
sw $ra, 0($sp)
slt $s1,$a1,$a0
bne $s1, 1, ELSE
jal multiply
ELSE: jal subtract
lw $ra, 0($sp)
addi $sp, $sp, 8
jr $ra
subtract:
sub $s0, $a0, $a1
jr $ra
multiply:
mult $a0, $a1
mflo $s0
jr $ra
The problem is, that after you return from multiply, you still call subtract in the next line. You have to return from the function test after calling multiply. However, since the function calls are both the last instruction of your function, you can use the following shortcut:
test:
slt $s1,$a1,$a0
bne $s1, 1, ELSE
j multiply
ELSE: j subtract
This way, you do not have to store the $ra in your stack, but you can directly use it to jump back to the caller of test in the jr $ra
of subtract and multiply. This way it should work as intended.
Alternatively, skip over jal subtract
after returning from multiply:
jal multiply
j OUT
ELSE: jal subtract
OUT: ...