I just wanted to create a program that reads a float (i.e. single-precision number) from the keyboard and then outputs it, and there're no warnings or errors, but I couldn't get correct answers, instead, I got 0.00000000. What's wrong with my code? This is my code:
.data 0x10000000
msg1: .asciiz "Please enter a float: "
.text
.globl main
main: addu $s0, $ra, $0 # save $31 in $16
li $v0, 4 # system call for print_str
la $a0, msg1 # address of string to print
syscall
li $v0, 6 # system call for read_float
syscall # the float placed in $f0
mtc1 $t0, $f0# move the number in $t0
sll $t0, $t0, 4
# print the result
li $v0, 2 # system call for print_float
mfc1 $t0, $f12 # move number to print in $f12
syscall
# restore now the return address in $ra and return from main
addu $ra, $0, $s0 # return address back in $31
jr $ra # return from main
You've got mtc1
and mfc1
backwards.
mtc1
means GPR -> FPR
mfc1
means GPR <- FPR
So if we take a look at what this code actually does:
mtc1 $t0, $f0 # Sets $f0 = $t0. You haven't specified a value for $t0 at this point,
# but it doesn't really matter since you're not using $f0 any more
# after this point.
sll $t0, $t0, 4 # Shifts whatever was in $t0 4 bits to the left.
li $v0, 2 # System call for print_float.
mfc1 $t0, $f12 # Set $t0 = $f12.
syscall # Calls print_float without having specified a value for $f12.
I don't understand the point of this shift since you say that you just want to print the number that was read, so the above code could be replaced with:
mov.s $f12, $f0
li $v0, 2
syscall
If you do still want to perform that shift for some reason, then you need to change your mtc1
to mfc1
and vice versa.
User contributions licensed under CC BY-SA 3.0