0

最適化の理由から、関数「fldl」と「fist」を直接(インラインアセンブラを使用して)呼び出すことを考えました。悲しいことに、私はアセンブラーの神ではないので、それを実行する方法がわかりません。

私はこれ以上進んでいませんでした:

double* input;         
long long output;

__asm fldl input;      
__asm fist output;
4

2 に答える 2

1

__asm fld input実際には、浮動小数点値であるかのようにポインタ値を読み取ろうとします。ポインタが指す浮動小数点値を読み取りたい場合は、2段階のプロセスを実行する必要があります。つまり、アドレスをレジスタに読み取り、次にレジスタ内のアドレスを使用してデータを読み取ります。32ビットプラットフォームでは、次のようなものになります。

__asm {
  mov eax, input
  fld qword ptr [eax]
  fistp output
}

VS2005で試したところ、動作します。(他の人がコメントで述べているように、fist64ビットへの保存はサポートしていませんが、サポートしlong longていることに注意してください。しかし、とにかく、つまりポップストアfistpが必要になるでしょう。)fistp

于 2012-11-30T16:53:30.167 に答える
1

最も簡単なのはおそらく:

double input;
long long output;

__asm fld input
__asm fisttp output

これは、Cキャストのように、「通常の」ダブルからロングロングへの変換を行い、ゼロに向かって切り捨てます。非常に古い(Pentium4より前の)CPUはサポートしていませんが、そのようなマシンでは、代わりに現在の丸めモード(通常は最も近い値に丸める)をfistpp使用する必要があります。fistpしたがって、たとえば-無限大に向かって丸める場合は、現在の丸めモードを保存し、必要なものに設定して、を実行しfistp、丸めモードを復元する必要があります。

double input;
long long output;
unsigned short oldcw, cw;

__asm fld input
__asm fstcw oldcw
cw = (oldcw & ~0xc00) | 0x400; // round towards -infinity
__asm fldcw cw
__asm fistp output
__asm fldcw oldcw
于 2012-11-30T17:43:05.917 に答える