私はMS Visual Studio(2005、ただし重要ではない)を使用しています。Visual Studioで__asmを使用してフローティングスタックにdoubleを返す
double f(double x)
{
__asm{ ...body code... }
}
アセンブリコードがST0に含ま返される結果で終了: Iは、その本体(必ずしも)実装されているインラインアセンブリに機能を有します。 使用されている呼び出し規約は__cdeclなので、ST0では戻り値doubleが返されるという規則があります。したがって、__asm {... body code ...}コードが完了すると、関数はスタッククリーンアップコードを実行して復帰させる準備が整います。しかし、上記のコードはコンパイルされません。なぜなら、 "return dblVal;"が存在しないからです。ステートメント。それはにコードを変更することによって補正することができます
が、これは2つの欠点があります。 (1)DRETにストアがすぐに完全な廃棄物や不要ですFLD DRET、続いている(これはされていますモンテカルロルーチンで無限の時間を使用していたので、すべてのサイクルがカウントされます) (2)さらに重要なことに、ST0の値は64ビットの仮数精度で体内で慎重に計算されています。続いてfldがこれを完全に殺します。
返されるdoubleが既にST0にあることをVisualStudioコンパイラにどのように伝えることができますか? 私は明示的に終了コードを書くことができます:
double f(double x)
{
__asm{ ...body code... }
__asm{ __asm leave
__asm ret
}
return 0.0; //dummy code that is never executed, to make the compiler happy
}
をが、その後1は、コンパイラが生成する(実際には、上記の終了コードが間違っている)というエントリーコードを知っている必要があります。これをさらに進めて、エントリーコードと終了コードの両方を書くことができます:
__declspec (naked) double f(double x)
{
__asm{ ...entry code...}
__asm{ ...body code... }
__asm{ ...exit code... }
return 0.0; //dummy code that is never executed, to make the compiler happy
}
これはすべて非常に醜いです。だから、どのように私は、エントリコードと出口コードを見て、戻り値はすでにST0にあることを伝えるようにコンパイラを得るのですか?
なぜ関数を宣言してから、内部構造をすべてインラインアセンブリに入れるのですか?なぜ、C宣言をスキップして、Cファイルのインラインアセンブリとは対照的に実際のアセンブリにしか関数が存在しないのはなぜですか? – TJD
メンテナンス性:これは非常に大きなアプリケーションの一部です。実際にアセンブリを統合する時間はありません。 –
正しいですが、適切なアセンブリを使用する方が良いでしょう。私はちょうどすべての作業(ほとんどの場合)を行う時間がありませんし、アセンブラのためのモジュールを作成するのではなく、すでにアセンブリ命令の恐怖で動いている他の開発者にとってはさらに混乱を招くでしょうプロジェクトに組み立てるなど) –