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

时间:2012-06-22 23:25:27

标签: gcc assembly double gas fpu

我一直在尝试使用GCC内联汇编将double加载到带有FLD的FPU。

由于不熟悉AT& T语法并且没有在网络上找到任何内容,我非常感谢您的帮助。 我的意图是将a的地址加载到EAX,然后加载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;
}

1 个答案:

答案 0 :(得分:5)

最简单的方法是使用constraint "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;
}

modifier "+"告诉编译器您希望输入在该内存位置并输出到同一位置。

允许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加载值,所以我不知道我的答案是否对你有用。 : - (

更新

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