1

cos関数値を取得するために、次のアセンブリ コードを実行しています。

float cosx( float radians ) {
    float result;

    __asm__ __volatile__ ( "fld %1;"
                            "fcos;"
                            "fstp %0;"
                            : "=m" (result)
                            : "m" (radians)
    ) ;
    return result ;
}

ただし、上記の関数は float 引数を受け入れることができ、取得される関数値も float 型です。したがって、私は double の引数を受け入れることができる同様の関数を作成していました。返される関数値も double の精度に達するはずです。

double cosx( double radians ) {
    double result;

    __asm__ __volatile__ ( "fld %1;"
                            "fcos;"
                            "fstp %0;"
                            : "=m" (result)
                            : "m" (radians)
    ) ;
    return result ;
}

ただし、2 番目の機能は正しく動作しないことが証明されています。したがって、2番目の機能をうまく機能させるために何をすべきか疑問に思っています。ありがとう!上記のコードをコンパイルするために gcc を使用しています。

編集: ここで、2番目の関数がうまく機能しない理由を示します:

int main() {
    float theta ;
    printf( "Enter theta  : " ) ;
    scanf( "%f", &theta ) ;  
     printf( "cosx(%f) = %lf\n", theta, cosx(theta) );  // line 5
     printf( "cosx(%f) = %lf\n", theta, cosx(double(theta)) ); // line 6

    return 0 ;
}

ご覧のとおり、line5 と line6 はそれぞれ最初と 2 番目の関数を呼び出します。それらが同じ値を持つことが期待されます。ただし、デモ プログラムの出力は次のようになります。

Enter theta in  :  0.5236 // pi/6
cos(0.5236) = 0.8660;
cos(0.5236) = 0.0000;
4

1 に答える 1

1

GCCは、オペランドの種類に注意を払っています。

__asm__ __volatile__ ( "fld %1;"
                        "fcos;"
                        "fstp %0;"
                        : "=m" (result)
                        : "m" (radians)

する必要があります:

__asm__ __volatile__ ( "fldl %1;"
                        "fcos;"
                        "fstpl %0;"
                        : "=m" (result)
                        : "m" (radians)

次のように書くこともできますが:

__asm__ __volatile__ ( "fldl %1;"
                      "fcos;"
                      : "=t" (result)
                      : "m" (radians)
                      ) ;

floatバージョンも同じ)

于 2012-12-26T18:59:40.893 に答える