使用GCC(内联汇编程序)将两倍加载到FPU

Mar*_*elL 2 double assembly gcc gnu-assembler fpu

我一直在尝试使用GCC内联汇编double将FP 加载到FPU FLD.

由于不熟悉AT&T语法并且没有在网络上找到任何内容,我非常感谢您的帮助.我的目的是要加载的地址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;
}
Run Code Online (Sandbox Code Playgroud)

kay*_*kay 5

最简单的方法是使用约束"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;
}
Run Code Online (Sandbox Code Playgroud)

修改"+"告诉你希望你在记忆位置,并输出到同一个位置输入的编译器.

允许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;
}
Run Code Online (Sandbox Code Playgroud)

现场演示:http://ideone.com/SuvpM.

PS:我无法让GCC加载双倍值,所以我不知道我的答案是否对你有用.:-(

更新:

得到它:你需要附加s(单个[32位],如flds浮点数加载单),l(对于双[64位]),或t(对于长双[80位])明确.我的GCC 4.6.3假设每个内存操作数都有一个值...