1

次のコードの for ループをアセンブリに変換したいのですが、開始方法がわかりません。それを行う方法とそれが機能する理由の説明をいただければ幸いです。

私はVS2010、C ++を使用して、x86用に書いています。コードは次のとおりです。

for (n = 0; norm2 < 4.0 && n < N; ++n) 
{
    __asm{
    ///a*a - b*b + x
        fld a // a
        fmul st(0), st(0) // aa
        fld b // b aa
        fmul st(0), st(0) // bb aa
        fsub // (aa-bb) // st(0) - st(1)
        fld x // x (aa-bb)
        fadd // (aa-bb+x)

    /// 2.0*a*b + y;
        fld d // d (aa-bb+x)
        fld a // d a (aa-bb+x)
        fmul // ad (aa-bb+x)
        fld b // b ad (aa-bb+x)
        fmul // abd (aa-bb+x)
        fld y // y adb (aa-bb+x)
        fadd // b:(adb+y) a:(aa-bb+x)

        fld st(0) //b b:(adb+y) a:(aa-bb+x)
        fmul st(0), st(0) // bb b:(adb+y) a:(aa-bb+x)
        fld st(2) // a bb b:(adb+y) a:(aa-bb+x)
        fmul st(0), st(0) // aa bb b:(adb+y) a:(aa-bb+x)
        fadd // aa+bb b:(adb+y) a:(aa-bb+x)
        fstp norm2 // store aa+bb to norm2, st(0) is popped.
        fstp b
        fstp a
    }
}
4

3 に答える 3

3

この種の問題を実行に移すための最も迅速で簡単な方法は、最初に C または C++ でできるだけ単純な形式でコードを記述し、次に C/C++ コンパイラを使用して asm を生成することです。この生成された asm は、独自の asm コードのテンプレートとして使用できます。gcc のような適切なコンパイラを使用gcc -Sすると、これを行うことができます。Visual Studio には同様のオプションが GUI のどこかに埋め込まれていると確信しています (明らかにコマンド ライン スイッチは です/Fa)。

于 2010-05-12T10:33:20.513 に答える
1

ここでは asm を書きませんが、調査すべき 3 つの点は次のとおりです。

  • すべてをレジスターに保管する

  • a^2 + b^2 に対して既に計算している場合、a^2-b^2 に対して a^2 と b^2 を再計算しないでください。

  • 反復せずに n を N に設定できる条件を見つけようとする

于 2010-05-12T10:57:27.290 に答える
0

forループはほぼ同じです

if norm2>=4.0 then  // note condition inversed.
  goto end;
if 0<N then
  goto end; 
beginloop:

  <asm block>

   if norm2>=4.0 then  // note condition inversed.
     goto end;
   if (n<N)  then
     goto beginloop
end:
于 2010-05-12T10:34:11.650 に答える