使用gcc编译汇编代码时,为什么会出现操作数类型不匹配错误?

时间:2012-12-26 14:27:57

标签: gcc assembly g++

如果给出角度,以下代码用于计算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'|

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

1 个答案:

答案 0 :(得分:2)

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

顺便说一句,这是非常恐怖的inline。

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

fldl    .LC0
fmuls   4(%esp)
fsin
ret