cvt.s.w指令在MIPS似乎不做任何事情



我的教授问"cvt.s.w指令是做什么的?"如果我们不使用它,会出现什么问题?">

在我的汇编程序中,即使我删除了这些代码行,程序仍然运行良好。是我遗漏了什么还是cvt.s.w在这个案例中什么都没做?下面是他提供的问题代码:

.data
THIRD:  .float 3.3
.text
li $t0, 10       # Put 10 in coprocessor
mtc1 $t0, $f0
cvt.s.w $f0, $f0
li $t0, 11       # Put 1.1 in coprocessor
mtc1 $t0, $f1
cvt.s.w $f1, $f1
div.s $f1, $f1, $f0
li $t0, 22       # Put 2.2 in coprocessor
mtc1 $t0, $f2
cvt.s.w $f2, $f2
div.s $f2, $f2, $f0
la $t0, THIRD        # Put 3.3 in coprocessor
l.s $f3, 0($t0)

add.s $f12, $f1, $f2 # Add and print results
add.s $f12, $f12, $f3
li $v0, 2
syscall
li $a0, 10       # Print newline
li $v0, 11
syscall
add.s $f12, $f2, $f3 # Add and print results
add.s $f12, $f12, $f1
li $v0, 2
syscall
li $v0, 10       # Exit program
syscall

你的教练在耍你。这些例子都是精心设计的,因此没有明显的变化。

你看过调试器中的值吗?

也许尝试打印各种中间值?

如果不使用cvt.s.w,中间体的值肯定是不同的。如果不进行转换,这些数字将被视为非常非常小的浮点值。

令人惊讶的是,除法仍然有效,因为数字之间的相对关系仍然存在。

同样,当我们在浮点数中计算一个大值+一个小值时,小值通常会消失。这样想:在3位数中,让我们将3.14加到0.000456。两个数的精度都是3位,但是把它们加起来会得到什么呢?3.14,三位数。

单浮点数只有大约6.5位的精度,所以非常小的数加上正常大小的数,唯一保持正常大小的数。

下面是一个完全相同的版本,但增加了中间值的打印。你会发现其中一些是完全不同的。

包含cvt.s.w输出为:

11.0
1.1
22.0
2.2
3.3000002
6.6000004
5.5
6.6
-- program is finished running --

和cvt.s.w排除输出为:

1.4E-44
1.5E-44
1.1
3.1E-44
2.2
3.3000002
6.6000004
5.5
6.6
-- program is finished running --
.data
THIRD:  .float 3.3
.text
li $t0, 10       # Put 10 in coprocessor
mtc1 $t0, $f0
cvt.s.w $f0, $f0
mov.s $f12, $f0
li $v0, 2
syscall
li $a0, 10
li $v0, 11
syscall
li $t0, 11       # Put 1.1 in coprocessor
mtc1 $t0, $f1
cvt.s.w $f1, $f1

mov.s $f12, $f1
li $v0, 2
syscall

li $a0, 10
li $v0, 11
syscall
div.s $f1, $f1, $f0

mov.s $f12, $f1
li $v0, 2
syscall
li $a0, 10
li $v0, 11
syscall
li $t0, 22       # Put 2.2 in coprocessor
mtc1 $t0, $f2
cvt.s.w $f2, $f2

mov.s $f12, $f2
li $v0, 2
syscall

li $a0, 10
li $v0, 11
syscall
div.s $f2, $f2, $f0

mov.s $f12, $f2
li $v0, 2
syscall
li $a0, 10
li $v0, 11
syscall
la $t0, THIRD        # Put 3.3 in coprocessor
l.s $f3, 0($t0)

add.s $f12, $f1, $f2 # Add and print results
li $v0, 2
syscall

li $a0, 10
li $v0, 11
syscall
add.s $f12, $f12, $f3
li $v0, 2
syscall
li $a0, 10       # Print newline
li $v0, 11
syscall
add.s $f12, $f2, $f3 # Add and print results
li $v0, 2
syscall

li $a0, 10
li $v0, 11
syscall
add.s $f12, $f12, $f1
li $v0, 2
syscall
li $v0, 10       # Exit program
syscall

最新更新