Search code examples
assemblymipsmips32qtspim

MIPS print float syscall only prints zero


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

Solution

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