2の補数の要点は、符号付きと符号なしの数値に対して同じ方法で操作を実装できることだと思いました。 ウィキペディアは、利益をもたらす演算の1つとして乗算を具体的にリストしています 。では、なぜx86にはmul
とimul
ごとに別々の命令があるのでしょうか。これはx86-64にも当てはまりますか?
足し算と引き算は同じで、掛け算の下半分も同じです。ただし、完全乗算はそうではありません。簡単な例:
32ビットの2の補数では、-1は符号なしの量2 ** 32-1と同じ表現になります。ただし:
-1 * -1 = +1
(2**32 - 1) * (2**32 - 1) = (2**64 - 2**33 + 1)
(両方の結果の下位32ビットは同じであることに注意してください。これは、「乗算の下位半分」が同じであると言うときの意味です)。
結果は、2オペランドバージョンと3オペランドバージョンで同じですが、mul命令とimul命令では、CFフラグとOFフラグの設定方法(キャリーとオーバーフロー)が異なります。
オーバーフローの観点から、-1 * -1と0xFFFFFFFF * 0xFFFFFFFFの2つのケースを考えてみてください。そうすれば、アイデアが得られます。
2つの16ビット数を乗算すると、32ビットの結果が得られます。数値の1つが「1」の場合でも、プロセッサは他の数値を実質的に32ビットに拡張します。数値をより長いビット長に拡張するプロセスは、符号付き値と符号なし値で異なる操作の1つです(符号が重要な他の重要な操作は、除算の重要な部分でもある大きさの比較です)。