2

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

由于不太熟悉 AT&T 语法,也没有在网上找到任何东西,我非常感谢您的帮助。我的意图是加载 to 的地址,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;
}
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 加载双精度值,所以我不知道我的回答是否对您有用。:-(

更新:

明白了:您需要显式附加s(对于单 [32 位],如flds浮点加载单)、l(对于双 [64 位])或t(对于长双 [80 位])。我的 GCC 4.6.3 假定每个内存操作数都有一个值……</p>

于 2012-06-22T23:54:12.877 回答