0

この問題にアプローチする方法を理解するのに本当に苦労しています。整数と小数の両方のバイナリ表現を取得し、それらを仮数に結合し、符号ビットを先頭に割り当てたいと思いますが、MIPS で実際に実装する方法がわかりません。

少なくとも始めるのを手伝ってくれる人はいますか?

MIPS ハードウェアに浮動小数点レジスタと浮動小数点 ALU がないと仮定します。浮動小数点加算を実行する場合は、整数レジスタ ($0 ~ $31) と整数 ALU を使用する MIPS 整数命令を使用して、ジョブを実行する必要があります。この割り当ての問題では、整数命令と整数レジスタのみを使用して MIPS コードを記述し、2 つの浮動小数点数を加算するプロシージャを実装し、プロシージャを呼び出すメイン関数を記述します。

  1. MIPS プロシージャ toFloat を記述して、浮動小数点数を IEEE 単精度形式に変換します。このプロシージャは、次のように浮動小数点数を表す $a0、$a1、$a2 の 3 つの整数を入力として取ります。浮動小数点数が負です。レジスタ $a1 に格納されている数値は浮動小数点数の整数部分であり、レジスタ $a2 に格納されている数値は浮動小数点数の小数部分です。たとえば、浮動小数点数 -5.25 を表示するには、3 つの入力レジスタに $a0 = 1、$a1 = 5、および $a2 = 25 の数値が含まれている必要があります。小数部分には、div rs rt を使用できます。 25 を 100 で割る命令. 分数は HI レジスタに格納され、mfhi 命令を使用して分数を取得できます。このプロシージャは、3 つの入力数値で表される浮動小数点数に対応する IEEE 単精度パターンを含む v0 を返します。この手順を実行したら、それを使用して入力数値 2.5 および 7.5 を IEEE 単精度形式に変換できます。

  2. MIPS プロシージャprintFloatを記述して、IEEE 単精度形式の数値を出力します。プロシージャの入力は、IEEE 単精度形式の数値である $a0 にあります。このプロシージャは、$a0 に格納されているビット パターンを単純に出力します。ループを使用して各ビットを出力できます。この手順を実行したら、それを使用して入力数値2.5および7.5を浮動小数点形式で出力できます。

  3. プロシージャを呼び出すメイン関数を実装する MIPS プログラムを作成します。このプログラムでは、

    toFloat(0, 2, 5) は 2.5 の浮動小数点形式を生成します。

    toFloat(0, 7, 5) は 7.5 の浮動小数点形式を生成します。

    2.5を印刷するprintFloat

    7.5を印刷するprintFloat

これが私がこれまでに持っているコードです:

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

4

1 に答える 1

1

わかりました、最初のステップ (コメントに記載されているように) は、ここにあるようなビットを表示するコンバーターで質の高い時間を過ごすことです: binaryconvert.com 浮動小数点コンバーター

次に、簡単な部分は、$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 が2 進数の小数部分になることを期待していました。しかし、そうではありません... $a1 は整数 (2 進数でも整数) であると言われていますが、$a2 は実際にはセントです。(25/100 = 10 進数で 0.25 の場合、$a2 にはセントが含まれます。)

ここで私自身、混乱しています。命令には、「div rs rt 命令を使用して 25 を 100 で割ります。分数は HI レジスタに格納されます」と書かれています。しかし、何をするかdiv( MIPS Instruction Reference ) を読むと、商を $LO に、余りを $HI に入れると書かれています。したがって、25 を 100 で割ると... 25 になります。これは、100 より大きい量を破棄する良い方法ですが、数値の 2 進分数表現にはなりません。

実際、クラス全体と昼食を費やして、0 から 99 までの数値を取得し、それを 100 で割り、FPU を使用せずに結果をバイナリに変換するエレガントな方法を見つけようとしました。私は不足しています。そこで、その部分についてプロに聞いてみましょう。

しかし、$a1 に整数部分があり、小数部分を表す 1 と 0 の文字列があれば (それを $s2 に入れましょう)、それを正規化する必要があります。に番号があり$a1ます。$s2であり、次の形式にする必要があります。

1.nnnnnnn

... ここでは 1 から始めますが、小数部分は 2 進数です。

動作する可能性のある疑似コードを次に示します。

  • msb が「1」になるまで $a1 を左にシフトします。$t0 にシフト数を格納します。(注: これは、整数部分が非ゼロであることを前提としています)
  • (31 - $t0) は指数を示します。バイアスによって調整し、浮動小数点結果のビット 30 ~ 23 に詰め込みます。
  • $t0 は、小数ビットにどれだけ余裕があるかも示します。$s2 を適切な量 (エンコード方法によって異なります) だけシフトしor、$a1 の最下位ビットを埋めるようにします。
  • IEEE FP では先頭の "1" が破棄されるため、$a1 をもう 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

符号 = 0

指数 = 10001110 (0x8E)

仮数 = 1000 0000 0000 0001 1000 000

(さて、これが実際に機能したことに対する私の驚きを想像してみてください!)

于 2013-10-22T01:10:14.527 に答える