2

GCCインラインアセンブリdoubleを使用してFPUにロードしようとしています。FLD

AT&T の構文に詳しくなく、Web 上で何も見つけられなかったので、助けていただければ幸いです。私の意図は、 to のアドレスをロードしaEAXからFLD [EAX]...

double atl(double a, int adr) {
    __asm ("movl ptr %0,%%eax"::"r"(a));
    __asm ("fld qword (%eax)");
    //.... some other code here
    __asm("movl ptr %0,%%eax"::"r"(a));
    __asm("fst qword (%eax)");
    return a;
}
4

1 に答える 1

6

最も簡単な方法は、制約 "m"を使用して、メモリ ロケーションからロード/保存することです。

#include <stdio.h>
int main (void) {
    double a = 0.78539816339744;
    asm ("fldl %0;"
         "fsin;"
         "fstpl %0" : "+m"(a));
    printf("sin(45°) = %f\n", a);
    return 0;
}

修飾子「+」は、入力をそのメモリ位置に置き、同じ位置に出力することをコンパイラに伝えます。

GCC は行を並べ替えることができますが、その行のセマンティクスを認識し、それに応じて最適化します。

書き込み対象以外の変数からの読み込みを使用する、より難しい例:

#include <stdio.h>
int main (void) {
    double sin_a, cos_a, a = 0.5;
    asm ("fldl %2;"
         "fsincos;"
         "fstpl %1;"
         "fstpl %0;" : "=m"(sin_a), "=m"(cos_a) : "m"(a));
    printf("sin(29°) = %f, cos(29°) = %f\n", sin_a, cos_a);
    return 0;
}

ライブデモ: http://ideone.com/SuvpM .

PS:ただし、GCCにdouble値をロードさせることができなかったので、私の答えがあなたに役立つかどうかはわかりません。:-(

アップデート:

わかりました: s(単精度 [32 ビット] の場合flds、浮動小数点ロード単精度の場合)、l(倍精度 [64 ビット] の場合)、またはt(倍精度浮動小数点 [80 ビット] の場合) を明示的に追加する必要があります。私の GCC 4.6.3 は、すべてのメモリ オペランドに対して単一の値を想定しています …</p>

于 2012-06-22T23:54:12.877 に答える