4

私たちのコース演習では、GNU アセンブリで delta = b2 - 4ac 関数を作成し、C からアクセスするように求められます。これはコンパイラに関するコースであり、アセンブリに関するコースではないため、教授は整数機能のみを示すことを選択し、整数を期待しています。関数。

しかし、私は個人的な学習が義務の要求を少し超えて、整数ではなく浮動小数点を返す使用可能な関数を作成したいと考えています.

私はこのCを思いつきました(グローバルを気にしないでください。次の演習の目的は、パラメーターを使用して適切な関数を作成することです):

# include <stdio.h>

extern float delta();
float a, b, c;

int main() {
    a = 3;
    b = 5;
    c = 4;
    printf("δ = %f\n", delta());
    return 0;
}

そしてこのGNU GAS:

.globl a
.globl b
.globl c
.globl delta
.f4: .float 4.0     # constante 4

.text
delta:
    fld b           # b sur la pile
    fmul b          # b2 sur la pile
    fld .f4         # 4 sur la pile 
    fmul a          # 4a sur la pile
    fmul c          # 4ac sur la pile
    fsubp           # b2 - 4ac sur la pile
ret

Google から、浮動小数点スタックの一番上に浮動小数点の結果を残す必要があると信じるようになりましたが、これは機能せず、C 呼び出し元に出力される結果は常に 0.0000000 です。

私は非常に小さな何かを見逃す必要がありますが、グーグルでそれを表示する量はありません.誰かが私を正しい方向に向けることができますか? ご清聴ありがとうございました。

4

1 に答える 1

3

それは私にとってはうまくいきます。呼び出し規約が異なるため、誤って 64 ビット モードを使用していないことを確認してください。つまり、gcc -g -m32 foo.c bar.sコンパイルに使用します。

とはいえ、修正すべき潜在的な問題もいくつか見られます。

  • グローバルは C コードで定義されているため.globl、アセンブリでは使用しないでください。どちらかといえば、を使用する必要があります.externが、GAS はそれを必要としません。
  • デフォルトのオペランド サイズに依存しないでください。メモリ オペランドがある場合はs、float にはサフィックスを、double にはサフィックスを明示的に使用する必要があります。lたとえばflds b、float としてロードされていることを確認します。
  • fsubrpスタックの一番上が であるため、使用する必要があります4ac。したがって、使用して計算するのfsubp4ac-b^2です。
于 2014-10-20T14:04:13.507 に答える