2011-01-06 22 views
2

32ビット浮動小数点を拡張精度の80ビット浮動小数点に変換しようとしています。 私はMSVC x86を使用しています。 void *outValueは10のバイトを保持するのに十分な大きさのバッファであり、ここで32ビット浮動小数点数をIEEE 80ビットに変換

void Convert32To80(float *value, void *outValue) 
{ 
    __asm 
    { 
     fld float ptr [value]; 
     fstp tbyte ptr [outValue]; 
    } 
} 

:私は、次のインラインASMコードを試してみました。 これは私には似ていますが、実行時にはクラッシュしています。

ご協力いただきましてありがとうございます。後世のため

+0

「実行時にクラッシュする」具体的なエラーは何ですか? – James

+0

私は特に具体的なエラーはありません。これはマネージドコードからロードされるC++/CLIのdllです(ASMのもの、他のインラインASMスタブがうまく動作します)。私はこれを得ます: "エラーのアドレスは0x64f9fca1、スレッド0x1904にありましたエラーコードは0xc0000005ですこのエラーは、CLRのバグ、このバグの一般的な原因には、COM-interopまたはPInvokeのユーザーマーシャリングエラーがあり、スタックを破損する可能性があります。 – Janiels

+1

クラッシュの原因となった命令は、デバッガに確認する必要があります。おそらくあなたのoutValueが悪いです(NULLなど)? – Suma

答えて

3

OK、これはそれを行う必要があります。

void Convert32To80(float *value, void *outValue) 
{ 
    __asm 
    { 
     mov eax,dword ptr [value] 
     fld dword ptr [eax] 
     mov ecx,dword ptr [outValue] 
     fstp tbyte ptr [ecx] 
    } 
} 

私は同じことを行うには、いくつかのCコードを書きましたが、ダブルコンバージョンにフロートのために、dissasemblyを見て、その後、必要に応じて変更されたなかったすべて。

私はMSVCの専門家ではなく、EAXとECXのレジスタを保存/復元せずに使用できるとは100%確信していません。他の人はもっと知り、訂正を提供するかもしれない。

+0

ありがとう!それはうまくいった。インラインASMの中の 'value'がスタック上のポインタになるとは思わなかった! もう一度ありがとう。 EAXとECXのレジスタについては、Intel ABIはそれらを保存せずに使用することができるので、問題ではないと言います。 – Janiels

+0

注意注意すべての人がインテルABIを完全に守っているわけではありません。彼らが確かに知っている唯一のものであるので、コンパイラのベンダーに確認することをお勧めします。 –

+0

@Brian、@Jakob私は同じことを考えていたが、自分自身を表現する方法がわからなかった。私は同様のルーチンを見ましたが、純粋なCでコード化され、floatをdoubleに割り当てるだけです。プロローグとエピローグは本質的に同一であった。しかし、私は同意します、私はレジスタの保存規約をチェックしたいと思いますが、私は実際にMSVCのほうがボーランドの人ではないことはほとんど知っていません。 –

1

更新注:どうやら、MSVC 2010は動作しません80ビット浮動小数点型のためのタイプなので、

float inValue = 666.666f; 
long double outValue = (long double)inValue; 

の線に沿ってCまたはC++コードでの明白な解決策を持っていない、とあなた実際にアセンブリ言語を直接使用するように強制されます。

+1

実際、MSVC 2010を除き、long doubleはdoubleの同義語で、64ビットです。 – Janiels

関連する問題