簡體   English   中英

擴展的內聯匯編GCC-編譯時表達式錯誤后,錯誤的寄存器名稱和垃圾內容“完成”

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

我正在使用匯編代碼編寫程序,以編寫計算二次方程根之一的程序。 我已經編寫了所有代碼,但是出現以下錯誤:

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

請問如何糾正這些錯誤?

我的代碼是:

// 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;
}

發生錯誤的行:

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

任何幫助,將不勝感激。

除了列出的錯誤之外,還有其他一些問題。 主要的原因是fld的默認操作數大小是單精度,而雙精度數則是。 因此,您需要顯式使用fldl 其次,如果您發現自己使用g約束,請三思,因為您可能做錯了什么。 在這種情況下,輸入操作數應為內存引用( m約束),而輸出應保留在FPU堆棧中( t約束)。 我現在已經刪除了處理狀態字的未使用代碼,我想這是一個占位符,用於檢測負數的平方根。

您應該始終注釋您的代碼,尤其是如果您要求他人提供幫助。 由於您還沒有這樣做,所以我不知道您最后想對eax做什么。 我也刪除了。

這是一個工作版本

#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