简体   繁体   English

扩展的内联汇编GCC-编译时表达式错误后,错误的寄存器名称和垃圾内容“完成”

[英]Extended Inline Assembly GCC- bad register name and junk 'done' after expression error when compiling

I'm writing a program using assembly code to write a program that calculate one of the quadratic equation roots. 我正在使用汇编代码编写程序,以编写计算二次方程根之一的程序。 I've written all of my code, but I have the following error: 我已经编写了所有代码,但是出现以下错误:

main.c:37: Error: bad register name `%qword'
main.c:39: Error: junk `done' after expression

How do I correct those error, please? 请问如何纠正这些错误?

My codes is: 我的代码是:

// function for checking that assembly code is computing the correct result
double quadraticRootC(double a, double b, double c)
{
    return (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
}

double quadraticRoot(double a, double b, double c)
{
    double root;

    asm(
        "fld        %1              \n"
        "fadd       %%ST            \n"
        "fld        %1              \n"
        "fld        %3              \n"
        "fmulp      %%ST(1)         \n"
        "fadd       %%ST            \n"
        "fadd       %%ST            \n"
        "fchs                       \n"
        "fld        %2              \n"
        "fld        %2              \n"
        "fmulp      %%ST(1)         \n"
        "faddp      %%ST(1)         \n"
        "ftst                       \n"
        "fstsw      %%1X            \n"
        "sahf                       \n"
        "fsqrt                      \n"
        "fld        %2              \n"
        "fchs                       \n"
        "fdivp      %%ST(1)         \n"
        "mov        %0, %%eax    \n"
        "fstp       %%qword, %%eax  \n"
        "mov        $1, %%eax       \n"
        "jmp        short done      \n"
        "done:                      \n"
        :"=g"(root)
        :"g"(a), "g"(b), "g"(c)
        :"eax"
        );
    return(root);
}

int main(int argc, char **argv)
{
    double  a, b, c;
    double  root, rootC;

    if (argc != 4) {
        printf("need 3 arguments: a, b, c\n");
        return -1;
    }
    a = atof(argv[1]);
    b = atof(argv[2]);
    c = atof(argv[3]);
    root = quadraticRoot(a, b, c);
    rootC = quadraticRootC(a, b, c);

    printf("quadraticRoot(%.3f, %.3f, %.3f) = %.3f, %.3f\n", a, b, c, root, rootC);

    return 0;
}

The line where the error occurs: 发生错误的行:

"mov        %0, %%eax    \n"
"fstp       %%qword, %%eax  \n"
"mov        $1, %%eax       \n"

Any help would be appreciated. 任何帮助,将不胜感激。

Apart from the errors you listed, there were some other issues. 除了列出的错误之外,还有其他一些问题。 The main one being that the default operand size for fld is single precision, while you have doubles. 主要的原因是fld的默认操作数大小是单精度,而双精度数则是。 So you need to explicitly use fldl . 因此,您需要显式使用fldl Second, if you ever find yourself using g constraint, think twice, because chances are you are doing something wrong. 其次,如果您发现自己使用g约束,请三思,因为您可能做错了什么。 In this case, the input operands should be memory references ( m constraint), and the output should be left in the FPU stack ( t constraint). 在这种情况下,输入操作数应为内存引用( m约束),而输出应保留在FPU堆栈中( t约束)。 I have removed the unused code dealing with the status word for now, I suppose that is a placeholder to detect taking the square root of a negative number. 我现在已经删除了处理状态字的未使用代码,我想这是一个占位符,用于检测负数的平方根。

You should always comment your code, but especially if you ask others for help. 您应该始终注释您的代码,尤其是如果您要求他人提供帮助。 Since you haven't done that, I have no idea what you wanted to do with eax at the end. 由于您还没有这样做,所以我不知道您最后想对eax做什么。 I removed that too. 我也删除了。

Here is a working version : 这是一个工作版本

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

// function for checking that assembly code is computing the correct result
double quadraticRootC(double a, double b, double c)
{
    return (-b + sqrt(b * b - 4 * a * c)) / (2 * a);
}

double quadraticRoot(double a, double b, double c)
{
    double root;

    asm(
        "fldl       %1       # a                   \n"
        "fadd       %%ST     # 2a                  \n"
        "fldl       %1       # a 2a                \n"
        "fldl       %3       # c a 2a              \n"
        "fmulp      %%ST(1)  # ac 2a               \n"
        "fadd       %%ST     # 2ac 2a              \n"
        "fadd       %%ST     # 4ac 2a              \n"
        "fldl       %2       # b 4ac 2a            \n"
        "fldl       %2       # b b 4ac 2a          \n"
        "fmulp      %%ST(1)  # b^2 4ac 2a          \n"
        "fsubp      %%ST(1)  # b^2-4ac 2a          \n"
        "fsqrt               # sqrt(b^2-4ac) 2a    \n"
        "fldl       %2       # b sqrt(b^2-4ac) 2a  \n"
        "fchs                # -b sqrt(b^2-4ac) 2a \n"
        "faddp      %%ST(1)  # -b+sqrt(b^2-4ac) 2a \n"
        "fdivp      %%ST(1)  # -b+sqrt(b^2-4ac)/2a \n"
        :"=t"(root)
        :"m"(a), "m"(b), "m"(c)
        );
    return(root);
}

int main(int argc, char **argv)
{
    double  a, b, c;
    double  root, rootC;

    if (argc != 4) {
        printf("need 3 arguments: a, b, c\n");
        return -1;
    }
    a = atof(argv[1]);
    b = atof(argv[2]);
    c = atof(argv[3]);
    root = quadraticRoot(a, b, c);
    rootC = quadraticRootC(a, b, c);

    printf("quadraticRoot(%.3f, %.3f, %.3f) = %.3f, %.3f\n", a, b, c, root, rootC);

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM