1. ホーム
  2. assembly

[解決済み] MIPSでディブディブ

2022-02-07 04:36:03

質問事項

とはどのような違いがあるのでしょうか。 divdivu をMIPSに搭載しました。

との違いを見たことがあります。 addaddu ( 同上リンク ). 私の理解では、addとadduはどちらも2の補数符号付き数値で演算します。 唯一の違いは、addはオーバーフロー時にトラップを発生させるが、adduは発生させないことである。

しかし、div と divu の違いは何ですか?つまり、ここではオーバーフローは発生しませんよね。

以下のケースを試しましたが、divuではかなり変な結果になりました。私は(mfloで)商をロードし、以下はその出力です。

num1 |  num2  | div num1 num2 (qoutient) | divu num1 num2 (qoutient) | 

5    |   2    |            2             |            2              |

-5   |   2    |           -2             |            2147483645     |

5    |  -2    |           -2             |            0              |

-5   |  -2    |            2             |            0              |

どなたか、何が起きているのか論理的に説明してくださいませんか?

どのように解決するのですか?

一般に u は符号なしを意味します。オーバーフロー・トラップは 副作用 サイン入り 一方、符号なし演算は例外を発生させることなく、オーバーフローや折り返しが許されます。

これが意味するのは、トラップを見る前に、符号付きと符号なしの違いを考えるべきだということです。通常の div 命令はオペランドを2補符号化したものとして扱いますが divu 演算はオペランドを符号なし整数として扱います。

つまり、同じオペランドを使っても、そのオペランドが div または divu が使用されます。

分割する場合 -5 によって 2div とすると,期待通りの答えが得られます:商が-2,余りが-1,これは,以下の理由から理にかなっています。 -2 * 2 + -1 = -5 . しかし divu これは符号なし整数を受け取る を使用することができます。 -5 は、quot;negative five"とはみなされず、むしろ 11111111111111111111111111111011 (の2の補数表現である)。 -5 というバイトで読み込まれます。 4294967291 で割ると 2 が正しく得られる。 2147483645 .

要するに、その目的は u のバージョンは、たとえそれがオーバーフローを引き起こすことができないとしても、入力を符号なし整数として処理することです。なぜこのようなものが存在するのでしょうか?たとえば、あなたが 4294967291/2 - 符号付き除算でどのようにそれを行うのでしょうか?を格納しようとすると 4294967291 を 32 ビットレジスタで使用すると、次のように解釈されることになります。 -5 ではなく 4294967291 . divu は、符号用に1ビットを確保するのではなく、レジスタの32ビットすべてを"data"として使用することでこの問題に対処しています。