次の手順で imul
が OF
を設定する理由がわかりません
mov al,48
移動 bl,4
imul bl ; AX = 00C0h、OF = 1
ただし、以下の手順ではしない
mov ax,48
移動 bx,4
imul bx ; DX:AX = 000000C0h、OF = 0
IMUL
は、適切なサイズの符号付き整数として解釈される結果の下位半分が、2 つの入力数値を乗算した数学的な結果と等しくない場合に、オーバーフロー フラグを設定します。
48 に 4 を掛けた数学的結果は 192 です。imul bl
の後に AL に残る値は C0h
です。数値 -64 を表す符号付き 8 ビット整数として。数学的には、192 と -64 は同じ数ではないため、オーバーフローを設定する必要があります。
imul bx
の後、AX に残る値は 00C0h
です。数値 192 を表す符号付き 16 ビット整数として。したがって、オーバーフロー フラグは設定されません。
同様に、下位半分を符号拡張すると完全な積とは異なる値が得られる場合、オーバーフロー フラグが設定されます。 8 ビット値 C0h
を 16 ビットに符号拡張すると、00C0h
と等しくない FFC0h
が得られるため、オーバーフローが設定されます。 . 16 ビット値 00C0h
を 32 ビットに符号拡張すると、実際の 32 ビット結果と等しい 000000C0h
が得られるため、オーバーフローは設定されません。
同様に、結果の上位半分のすべてのビットが下位半分の符号ビットと等しい場合にのみ、オーバーフロー フラグがクリアされます。 8 ビット値 C0h
の符号ビットは 1 ですが、上位半分は FFh ではなく、00h であるため、オーバーフローが設定されます。 16 ビット値 00C0h
の符号ビットは 0 で、上位半分は 0000h
なので、オーバーフローはクリアされます。
OF
は、値を変更せずに倍幅の完全な結果を入力幅に切り詰めることができるかどうかを示します。 (imul
の 2 の補数の整数として解釈される場合1、mul
の符号なし 2 進整数。)
0xC0
は負の 8 ビット数のビット パターンですが、0x00C0
は正の 16 ビット数です。
これは、 のような他の 8 ビットまたは 16 ビット操作のシーケンスの一部として
、結果の上位半分を使用する予定はありません。imul
または mul
を使用している場合に知りたいことです。追加
(または、狭いバージョンが分岐する価値があるほど高速である場合は、より広いサイズを処理する拡張精度バージョンにフォールバックすると便利です。)
既に出力の全幅を使用しようとしている場合は、OF/CF をチェックしないでください。拡大乗算は、出力ビットを失うという意味でオーバーフローすることはありません。 2 つの N ビット数の積は、常に 2N ビットで表すことができます。
脚注 1: imul cx, dx, 123
のように上位半分をどこにも書き込まない 2 オペランドと 3 オペランドの形式を含めます。通常、その形式は符号付きまたは符号なしの拡大を行わない数学に使用しますが、符号なしの乗算がいつラップされたかを検出したい場合は、 mul
を使用することをお勧めします。 EAX で、EDX:EAX に出力があります。 C での imulq と unsigned long long オーバーフロー検出を参照してくださいとアスム