1

私は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にあることを伝えるようにコンパイラを得るのですか?

+3

なぜ関数を宣言してから、内部構造をすべてインラインアセンブリに入れるのですか?なぜ、C宣言をスキップして、Cファイルのインラインアセンブリとは対照的に実際のアセンブリにしか関数が存在しないのはなぜですか? – TJD

+0

メンテナンス性:これは非常に大きなアプリケーションの一部です。実際にアセンブリを統合する時間はありません。 –

+0

正しいですが、適切なアセンブリを使用する方が良いでしょう。私はちょうどすべての作業(ほとんどの場合)を行う時間がありませんし、アセンブラのためのモジュールを作成するのではなく、すでにアセンブリ命令の恐怖で動いている他の開発者にとってはさらに混乱を招くでしょうプロジェクトに組み立てるなど) –

答えて

2

実は、私の質問への答えは、私は上記の質問の文の中で一つのことについて間違っていたということです:任意のreturn文なし

double f(double x) 
{ 
    __asm{ ...body code... } 
} 

、体内の__asm文で、うまくコンパイルエラーや警告は表示されません。コンパイラは、戻り値が適切に返されるように(正しく)仮定しています。コンパイラは正しくエントリと終了コードを生成し、残りの部分は私に残して幸せです。 Go figure - なぜ私はそれをテストし、コンパイルエラーが見つかったと思いましたか?一口。誰も気にして申し訳ありません。

0

あなたは唯一のオプションは裸の関数ですが、C return文を必要とせず、スタックフレームを実行する必要もありません。しかし、あなたが本当にasmを使う良い理由がない限り、C言語でのやり方は、多くの理由、主に移植性、そして他のものはSIMDのようなターゲット固有の最適化です。

+0

私はアセンブリを使用する本当に良い理由があります:80ビットの精度で一連の計算が必要で、非常に高速に処理する必要があります。 SIMDは絶対に必要なものではありません。精度は高く、精度は低くする必要があります。 –

関連する問題