I have a very unusual problem that I can't figure out, and couldn't find a solution anywhere.
I have written a code for calculating exponentiation of floating point numbers in MIPS. The Algorithm works fine but in the end when the syscall should print the returned value, it prints only 0.
Following is the code used to print the returned value, it seems perfectly fine to me, I have no clue whats wrong.
mov.s $f12, $f31
li $v0, 2
syscall
I tried to debug the code in qtSpim and everything seems to work fine, even the values in respected registers are correct at the time of syscall.
The values in registers seem to be fine, 4 * 4 = '16' in decimal or '10' in hex.
.text
main:
addi $v0,$zero,4
la $a0,enter
syscall
li $v0, 6
syscall
mtc1 $t0, $f10
add.s $f31,$f0,$f10
addi $v0,$zero,4
la $a0,enter_2
syscall
li $v0, 5
syscall
mtc1 $t0, $f10
add.s $f12,$f31,$f10 # $a0 = x
addu $a0,$v0,$zero # $a1 = n
jal exp
mtc1 $t0, $f10
add.s $f31, $f0, $f10 #Save returned value
addi $v0,$zero,4
la $a0,result
syscall
mov.s $f12, $f31
li $v0, 2
syscall
addi $v0,$zero,4
la $a0,end
syscall
addi $v0,$zero,10
syscall
exp:
mtc1 $t0, $f10
add.s $f12,$f12,$f10 # let $f12 = x;
addu $s1,$a0,$0 # let $s1 = n
li $t1, 1
mtc1 $t1, $f11
add.s $f31, $f10, $f11 # f31=r=1;
add.s $f1, $f12, $f10 # f1=p=s0;
while:
and $t3, $s1, $t1
bne $t3,$t1,if_1
mul.s $f31, $f31, $f1
if_1:
srl $s1, $s1, $t1
bne $s1, $zero, if_2
add.s $f0, $f31,$f10
jr $ra
if_2:
mul.s $f1,$f1,$f1
j while
jr $ra
.data
enter: .asciiz "\nPlease enter a number : "
enter_2: .asciiz "\nPlease enter an exponent : "
result: .asciiz "\nResult : "
end: .asciiz "\n\nThe End :)"
You should comment your code, especially if you want others to help. It's unclear what you are trying to do at places, and what you are using particular registers for. Also, if you really had those register values, the result should have printed correctly.
Example:
mtc1 $t0, $f10
add.s $f12,$f12,$f10 # let $f12 = x;
I think you expect $t0
to be zero everywhere (which it isn't) but even then this makes no sense, you just add zero to $f12
. Why?
li $t1, 1
mtc1 $t1, $f11
add.s $f31, $f10, $f11 # f31=r=1;
That does not set $f11
to 1
since you didn't convert it from int to float. Also, if you still assume $f10
to be zero (which it wasn't to start with) then why not just load into $f31
directly?
I have cleaned it up a little, and this seems to work correctly:
.text
main:
addi $v0,$zero,4
la $a0,enter
syscall
li $v0, 6
syscall
mov.s $f31,$f0
addi $v0,$zero,4
la $a0,enter_2
syscall
li $v0, 5
syscall
add.s $f12,$f31,$f10 # $a0 = x
addu $a0,$v0,$zero # $a1 = n
jal exp
mov.s $f31, $f0 #Save returned value
addi $v0,$zero,4
la $a0,result
syscall
mov.s $f12, $f31
li $v0, 2
syscall
addi $v0,$zero,4
la $a0,end
syscall
addi $v0,$zero,10
syscall
exp:
addu $s1,$a0,$0 # let $s1 = n
li $t1, 1
mtc1 $t1, $f0
cvt.s.w $f0, $f0 # f0=1, the result
while:
and $t3, $s1, $t1
bne $t3, $t1, not_set
mul.s $f0, $f0, $f12 # include this power
not_set:
mul.s $f12, $f12, $f12 # next power
srl $s1, $s1, $t1
bne $s1, $zero, while
jr $ra
.data
enter: .asciiz "\nPlease enter a number : "
enter_2: .asciiz "\nPlease enter an exponent : "
result: .asciiz "\nResult : "
end: .asciiz "\n\nThe End :)"