2
votes

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.

Sample Output :

enter image description here

FP Registers while printing the result:

The values in registers seem to be fine, 4 * 4 = '16' in decimal or '10' in hex.

enter image description here

Complete Code :

.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 :)"
1
Why are you using $t0 without having initialized it to anything? Also, the fact that you're doing add.s directly after an mtc1 without any cvt.s.w looks suspicious.Michael
@Michael, i intended to use $0 instead of $t0. I have changed it and the appropriate cvt.s.w changes. What I don't get is that the result is stored in $f12 but still not printedTaha Rushain
@Michael, wow adding the appropriate cvt.s.w statements worked. Thanks a bunch!Taha Rushain

1 Answers

2
votes

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 :)"