1

私が得たと言う

EDX = 0xA28

EAX = 0x0A280105

このASMコードを実行します

IMUL EDX

私の理解では、これはEAXのみを使用します。1つのオペランドが指定されている場合

したがって、Cコードでは次のようになります。

EAX *= EDX;

正しい?

デバッガーを調べた後..私EDXも変更されていることがわかりました。

0x0A280105 * 0xA28 = 0x67264A5AC8

デバッガーで

EAX = 264A5AC8 EDX = 00000067

今、あなたが答えを取り、0x67264A5AC8最初のヘックスペアを分割すると、0x67 264A5AC8 なぜEDXEAXがそのようになっているのかがはっきりとわかります。

さて、オーバーフローが発生します。32ビットにそのような膨大な数を格納できないためです。そのため、EDXで余分な8ビットを使用し始めます

しかし、私の質問は、同じ結果を得るために、Cコードでこれをどのように行うのかということです。

こうなると思います

EAX *= EDX;
EDX = 0xFFFFFFFF - EAX; //blah not good with math manipulation like this.
4

1 に答える 1

2

IMUL命令は、実際にはオペランドの2倍のサイズの結果を生成します(宛先を指定できる新しいバージョンの1つを使用する場合を除く)。それで:

imul 8bit -> result = ax, 16bits
imul 16bit -> result = dx:ax, 32bits
imul 32bit -> result = edx:eax, 64bits

Cでこれを行うにはコンパイラーに依存しますが、これを行うために機能するものもあります。

long result = (long) eax * (long) edx;
eax = result & 0xffffffff;
edx = result >> 32;

これは、longが64ビットであることを前提としています。コンパイラに64ビットのデータ型がない場合、結果の計算は非常に難しくなり、長い乗算を行う必要があります。

あなたはいつでもimul命令をインライン化することができます。

于 2011-10-13T08:48:15.903 に答える