GNU アセンブラーでは$、リテラル値 (命令にエンコードされる値) を指定します。ラベルの値はそのアドレスです。$x、$format、$result、およびは、これらのラベル$textのアドレスです。それらは、ラベル付けしている値があるアドレスです。printfのアドレスを使用しません%f。アドレスではなく、浮動小数点数の値を渡す必要があります。doubleまた、Frank Kotler が指摘しているように、32 ビットではなく64 ビットとして渡す必要がありますfloat。
add $-8, %espこれを行う最も簡単な方法は、命令の前に(またはadd %esp, $-8、アセンブラー バージョンのオペランドの順序に応じて)を挿入し、アセンブラーに応じて命令をまたはにFSTS result変更することです。(また、浮動小数点スタックから値をそのままにしておくのではなく、そこから値をポップしたり、ポップしたりすることもできます。)次に、 .FSTS resultFST (%esp)FSTL (%esp)FSTP (%esp)FSTPL (%esp)push $result
これらの変更により、スタック (add命令内) に 8 バイトが割り当てられ、浮動小数点の結果がそれらの 8 バイトに格納されます。
また、あなたのコードは、呼び出されたルーチンに渡された引数をクリーンアップする責任があると思います.2つの引数をポップするために呼び出した後、スタックポインタに8を追加し、新しい8バイトの引数をポップするためscanfに呼び出した後、12を追加する必要があります.printfフォーマット文字列の 4 バイト アドレス。を呼び出してプログラムを終了するため、これらの変更がなくてもプログラムが動作する場合がありますexit。retただし、スタックをクリーンアップせずに命令を使用してルーチンから戻ることはできません。
補足
次のコードはideone.comで動作し、アセンブラー (gcc-4.7.2) の 2 番目の選択肢を使用しています。
.text
text: .asciz "Function result: %4.2f \n"
.data
x: .float 2.0
one: .float 1.0
result: .float 0.0
format: .asciz "%f"
.global main
main:
push $x
push $format
call scanf
add $8, %esp
FINIT
FLDS x
FMULS x #x*x
FADDS one
FSQRT
FSUB one
add $-8, %esp
FSTPL (%esp)
xor %eax, %eax
push $text
call printf
add $12, %esp
pushl $0
call exit