MIPSを使用していると思われるpcsimプログラムを使用しています。私はアセンブリ言語に非常に慣れていないので、前向きではありません。加算とシフトのみを使用して2つの32ビット数を乗算し、積を2つのレジスタに格納する必要があります。結果を32ビットで格納できれば、2つの数値を正常に乗算できるようになりました。問題は、それよりも数が多いと、製品の右半分と左半分を組み合わせる方法がわからないことです。左半分のレジスタは、2^32から始まる値をずっと保持する必要があります。これが明確でない場合は、さらに説明することができます。これを達成するために私が見落としている簡単な方法はありますか?助けてくれてありがとう。
2 に答える
私の理解が正しければ、実際に 64 ビット演算を行う必要がある時点で行き詰っていますよね?
典型的なシフト アンド 加算バイナリ long 乗算を実行している場合は、32 ビット演算から 64 ビット シフトおよび加算プリミティブを作成してから、同じ方法を使用できます。
C フラグメントとしていくつかの例を次に示します (MIPS を実際に使用している場合は、MIPS に変換するのは簡単なはずです)。符号なし 32 ビットの数値を扱っていて、符号なし 64 ビットの結果が必要だと仮定しています。
論理左シフト 1 ビット:
tmp = lo >> 31; /* top bit of lo to bottom bit of tmp, rest of tmp is 0 */
lo <<= 1;
hi <<= 1;
hi |= tmp;
論理右シフト 1 ビット:
tmp = hi << 31; /* bottom bit of hi to top bit of tmp, rest of tmp is 0 */
hi >>= 1;
lo >>= 1;
lo |= tmp;
1
(実際には、 and31
をn
andに置き換えて、(32 - n)
他のビット数だけシフトすることができます)
64 ビット追加:
result_lo = a_lo + b_lo;
result_hi = a_hi + b_hi;
if (result_lo < a_lo)
result_hi++;
(詳細については、MIPS への特定の参照とともに、こちらを参照してください)。
別のアプローチは、32 ビット入力のそれぞれを 16 ビットの「数字」のペアとして扱うことです。2 つの 16 ビット数を乗算すると、最大で 32 ビットの結果が得られます。したがって、基本的な考え方は次のようになります。
0x12345678 * 0x23456789 = 0x5678 * 0x6789
+ ((0x1234 * 0x6789) << 16)
+ ((0x5678 * 0x2345) << 16)
+ ((0x1234 * 0x2345) << 32)
(まだ 64 ビットの追加が必要です)。
2つの半分を1つの32ビットレジスタに「結合」する方法はありません。2つの半分をメモリ内の1つの64ビット値に結合する場合は、マシンのエンディアンに応じて、両方の半分を互いに別の場所に格納する必要があります。SPIMを使用している場合は、ホストコンピューターと同じエニアンネスを使用しているように見えます。
X86?スモールエンディアン。下半分を最初に保管してください。PPC?ビッグエンディアン。上半分を先に保管してください。