MIPS - 如何将一组整数转换为单精度浮点数

时间:2013-10-21 15:49:25

标签: floating-point integer mips mars-simulator single-precision

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

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

  

假设您的MIPS硬件没有浮点寄存器和浮点ALU。如果   如果要执行浮点加法,则必须使用使用的MIPS整数指令   整数寄存器($ 0 - $ 31)和整数ALU来完成工作。在这个作业问题中,   你将编写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除以。分数将存储在HI寄存器中,您可以使用 用于检索分数的mfhi指令。 该过程将返回v0,其中包含对应于的IEEE单精度模式 由三个输入数字表示的浮点数。 完成此过程后,您可以使用它将输入数字2.5和7.5转换为它们 IEEE单精度格式。

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

  3. 编写MIPS程序以实现调用程序的主函数。在这个程序中,你 将致电

      

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

         

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

         

    printFloat打印2.5

         

    printFloat打印7.5

  4. 以下是我到目前为止的代码:

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

1 个答案:

答案 0 :(得分:0)

好的,第一步(如评论中所述)是花一些时间与转换器一起显示位,如下所示: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寄存器中”。但是,当我阅读div所做的事情(MIPS Instruction Reference)时,它会将商数放在$ 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左移一位,因为在IEEE FP
  • 中丢弃了前导“1”
  • 将$ 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

Sign = 0

指数= 10001110(0x8E)

尾数= 1000 0000 0000 0001 1000 000

(现在,试着想象一下这实际上有用了!)