0

我真的很难弄清楚如何解决这个问题。我知道我想采用整数和小数的二进制表示,将它们组合为尾数,并将符号位分配给开头,但我不知道如何在 MIPS 中实际实现它。

任何人都可以帮助我至少开始吗?

假设您的 MIPS 硬件没有浮点寄存器和浮点 ALU。如果要执行浮点加法,则必须使用使用整数寄存器 ($0 - $31) 和整数 ALU 的 MIPS 整数指令来完成工作。在这个赋值问题中,您将编写 MIPS 代码,仅使用整数指令和整数寄存器,来实现一个将两个浮点数相加的过程,并编写一个 main 函数来调用该过程。

  1. 编写 MIPS 过程 toFloat 以将浮点数转换为 IEEE 单精度格式。该过程以三个整数为输入:$a0、$a1、$a2,分别代表一个浮点数:如果 $a0 包含 0,则浮点数为正数,否则如果 $a0 包含 1,则浮点数为负数。寄存器$a1 中存储的数字是浮点数的整数部分,寄存器$a2 中存储的数字是浮点数的小数部分。例如,要显示浮点数 -5.25,三个输入寄存器应包含以下数字:$a0 = 1、$a1 = 5 和 $a2 = 25。对于小数部分,您可以使用 div rs rt将 25 除以 100 的指令. 分数将存储在 HI 寄存器中,您可以使用 mfhi 指令检索分数。该过程将返回 v0,其中包含对应于由三个输入数字表示的浮点数的 IEEE 单精度模式。完成此过程后,您可以使用它将输入数字 2.5 和 7.5 转换为其 IEEE 单精度格式。

  2. 编写 MIPS 过程printFloat以打印 IEEE 单精度格式的数字。过程的输入是 $a0,它是一个 IEEE 单精度格式的数字。该过程将简单地打印存储在 $a0 中的位模式。您可以使用循环打印每个位。完成此过程后,您可以使用它以浮点格式打印输入数字2.57.5 。

  3. 编写一个 MIPS 程序来实现 main 函数来调用你的程序。在这个程序中,您将调用

    toFloat(0, 2, 5) 生成 2.5 的浮点格式;

    toFloat(0, 7, 5) 生成 7.5 的浮点格式;

    printFloat 打印 2.5

    printFloat 打印 7.5

这是我到目前为止的代码:

http://s7.postimg.org/v39ufikaj/code.png

4

1 回答 1

1

好的,第一步(如评论中所述)是花一些时间使用显示位的转换器,就像这里的一个:binaryconvert.com floating point converter

然后,简单的部分是取 $a0 并将位 0 ​​转储到我们结果的位 1 中。就像是:

add $v0, $zero, $zero # initialize our result
sll $t0, $a0, 31 # shift the lsb to the msb
or $v0, $v0, $t0 # set the sign bit in the result

但现在我们必须做数学。我希望 $a1 是整数部分,而 $a2 是二进制小数部分。但事实并非如此......他们说 $a1 是整数(仍然是二进制整数),但 $a2 实际上是美分。(如果 25/100 = 0.25 十进制,则 $a2 包含美分。)

这就是我自己感到困惑的地方。指令说“使用 div rs rt 指令将 25 除以 100。分数将存储在 HI 寄存器中”。但是当我读到什么divMIPS 指令参考)时,它说它将商放在 $LO 中,将余数放在 $HI 中。因此,将 25 除以 100 将得到... 25。这是丢弃大于 100 的数量的好方法,但它不会让我们得到数字的二进制小数表示。

事实上,我花了一整堂课和午餐时间试图找出一种优雅的方法来取 0 到 99 之间的数字,除以 100,然后在不使用 FPU 的情况下将结果转换为二进制。我来不及了。所以我会让你问教授这部分。

但是一旦我们在 $a1 中有整数部分,以及代表小数部分的 1 和 0 字符串(让我们把它放在 $s2 中),我们只需要对其进行规范化。我们有一个号码$a1$s2,我们需要它采用这种格式:

1.nnnnnnn

...我们从 1 开始,然后小数部分是许多二进制数字。

这是一些可能有效的伪代码。

  • 左移 $a1 直到 msb 为“1”。在 $t0 中存储班次数。(注意:这假设整数部分是非零的)
  • (31 - $t0) 给你指数。通过偏差调整它并填充到浮点结果的 30-23 位。
  • $t0 还告诉您小数位有多少空间。将 $s2 移动适当的量(这取决于它的编码方式),or以便它填充 $a1 的最低有效位
  • 将 $a1 再左移一位,因为前导“1”在 IEEE FP 中被丢弃
  • 将 $a1 的前 23 位填充到浮点结果的 22-0 位中

让我们看看这是否适用于示例。$a1 具有 0x0000C000 的整数部分,并且 $s2 以某种方式加载了 0.75 (1 x 2^-1 + 1 x 2^-2)

$a1: 0000 0000 0000 0000 1100 0000 0000 0000 
$s2: 1100 0000 0000 0000 0000 0000 0000 0000

我必须移动 $a1 16 次:

$a1: 1100 0000 0000 0000 0000 0000 0000 0000 

这应该给我一个 31 - 16 = 15 的指数。加上 127 的偏差,我得到 142 (0x8E)。这在指数部分。

我需要将 $s2 右移相同的数量(16):

$s2: 0000 0000 0000 0000 1100 0000 0000 0000

or那些在一起:

$a1:  1100 0000 0000 0000 1100 0000 0000 0000

用小数点可视化:

original:  1100 0000 0000 0000.1100 0000 0000 0000
normaliz: 1.100 0000 0000 0000 1100 0000 0000 0000

因为我们省略了小数点左侧隐含的“1”,所以将其移出,我们有:

$a1:  100 0000 0000 0000 1100 0000 0000 0000 0

取其中的 23 位。因此,如果我做对了,上面的转换器应该说 49152.75 在 IEEE FP 中存储为:

01000111 01000000 00000000 11000000

符号 = 0

指数 = 10001110 (0x8E)

尾数 = 1000 0000 0000 0001 1000 000

(现在,试着想象一下我对这真的有效的惊讶!)

于 2013-10-22T01:10:14.527 回答