【问题标题】:Why will I have operand type mismatch error when compiling the assembly codes with gcc?为什么使用 gcc 编译汇编代码时会出现操作数类型不匹配错误?
【发布时间】:2012-12-26 14:27:56
【问题描述】:

如果给定角度,以下代码用于计算sincos 值。为了尽可能快地计算这些函数,采用了汇编代码实现。

#include <stdio.h>

float sinx( float degree ) {
    float result, two_right_angles = 180.0f ;
    __asm__ __volatile__ ( "fld %1;"
                            "fld %2;"
                            "fldpi;"
                            "fmul;"
                            "fdiv;"
                            "fsin;"
                            "fstp %0;" 
                            : "=g" (result) 
                            : "g"(two_right_angles), "g" (degree)
    ) ;
    return result ;
}

float cosx( float degree ) {
    float result, two_right_angles = 180.0f, radians ;
    __asm__ __volatile__ ( "fld %1;"
                            "fld %2;"
                            "fldpi;"
                            "fmul;"
                            "fdiv;"
                            "fstp %0;" 
                            : "=g" (radians) 
                            : "g"(two_right_angles), "g" (degree)
    ) ;
    __asm__ __volatile__ ( "fld %1;"
                            "fcos;"
                            "fstp %0;" : "=g" (result) : "g" (radians)
    ) ;
    return result ;
}

float square_root( float val ) {
    float result ;
    __asm__ __volatile__ ( "fld %1;"
                            "fsqrt;"
                            "fstp %0;" 
                            : "=g" (result) 
                            : "g" (val)
    ) ;
    return result ;
}

int main() {
    float theta ;
    printf( "Enter theta in degrees : " ) ;
    scanf( "%f", &theta ) ;

    printf( "sinx(%f) = %f\n", theta, sinx( theta ) );
    printf( "cosx(%f) = %f\n", theta, cosx( theta ) );
    printf( "square_root(%f) = %f\n", theta, square_root( theta ) ) ;

    return 0 ;
}

以上代码来自here,我正在尝试用gcc编译以上代码:

g++ -Wall -fexceptions  -g     -c /filename.cpp  

但是,它失败了,并给出了以下错误消息:

Error: operand type mismatch for `fstp'|
Error: operand type mismatch for `fstp'|

我想知道为什么编译会失败以及如何成功编译它们。谢谢!

【问题讨论】:

    标签: gcc assembly g++


    【解决方案1】:

    manual 表示g 约束:Any register, memory or immediate integer operand is allowed, except for registers that are not general registers。编译器可能选择了fstp 不接受但符合约束条件的寄存器。

    顺便说一句,这是相当可怕的内联汇编。

    还请注意,仅仅因为某些东西在 asm 中,它不一定会更快。编译器非常有能力优化事物,它也做得更好。您可能对-ffast-math 开关感兴趣。编译器从return sin(degree * M_PI / 180); 生成这段代码:

    fldl    .LC0
    fmuls   4(%esp)
    fsin
    ret
    

    【讨论】:

    • 我现在把'g'换成'm',就可以编译成功了。我会将此实现与您建议的方法进行比较。谢谢!
    猜你喜欢
    • 2019-02-17
    • 1970-01-01
    • 1970-01-01
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    • 2014-03-24
    相关资源
    最近更新 更多