Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C x87双加法不起作用_C_Assembly_X86 64_Att_X87 - Fatal编程技术网

C x87双加法不起作用

C x87双加法不起作用,c,assembly,x86-64,att,x87,C,Assembly,X86 64,Att,X87,我定义了一个汇编函数,它接受三个参数int,double,double,这三个参数应该加上两个putted double值,并返回这个加法的结果。我不知道为什么下面的代码不起作用: extern double ftaylor(unsigned int n, double x, double y); int main() { double z = 14; z = ftaylor(30, 13.45, 7); printf("%f", z); return 0;

我定义了一个汇编函数,它接受三个参数int,double,double,这三个参数应该加上两个putted double值,并返回这个加法的结果。我不知道为什么下面的代码不起作用:

extern double ftaylor(unsigned int n, double x, double y);
int main()
{
    double z  = 14;
    z = ftaylor(30, 13.45, 7);


    printf("%f", z);
    return 0;
}
以及装配功能:

.globl ftaylor

ftaylor:
    .lcomm state, 8
    .lcomm state2, 8
    push %rbp
    mov %rsp, %rbp
    push %rax

    mov %rdi, %rax
    movsd %xmm0, state
    movsd %xmm1, state2

    finit

    fld state
    fld state2

    fadd %st(1), %st(0)

    fstp state
    fstp state2

    movsd state, %xmm0

    pop %rax
    mov %rbp, %rsp
    pop %rbp
    ret
终端上打印的结果为13.45。看起来处理器没有执行加法。我不知道为什么。

根据x87代码片段计算的状态会被存储在xmm0中的值覆盖:

...
movsd %xmm0, state
...
... x87 calculation of state ...
...
movsd state, %xmm0
...
经过一番反复之后,似乎AT&T语法可能会使用相反的参数顺序,也就是说,mov a,b从b移动到a,这将解释输入参数的覆盖,以及OP观察到的输出。不过,他的汇编程序使用的确切语法仍然不清楚,所以我对这个答案有点怀疑


其他答案和评论中还指出了其他可能的原因。

主要问题是,不带后缀的fld/fstp默认为short,即单精度浮点。但是您有双精度值,所以应该使用fldl/fstpl。正如其他人指出的,除非绝对必要,否则不要使用x87。另外,学习使用调试器。

unsigned int n的参数是什么?如果不是13.45,那么您希望两个双精度值13.45+0的总和是多少?有什么特殊原因不通过堆栈将参数从%xmm寄存器移动到FPU?使用静态变量似乎很奇怪。SSE和x87的这种亵渎神明的混合是什么??而且,如前所述,您只需覆盖状态。更不用说覆盖部分-AT&T语法欺骗了我!不过,你为什么不用SSE计算一切呢?而且,如前所述,在给定输入的情况下,您的输出是正确的。为什么不添加SD%xmm1,%xmm0?不需要使用x87来添加浮点数。呃,不需要。x87计算的结果会保存到状态,但是OP使用的任何ABI都可能要求浮点返回位于%xmm寄存器中,所以这就是movsd状态%xmm0所做的。您的意思是,此程序集表示法使用mov from,to,而不是mov to,from?