2012-02-25 6 views
0

私は大学のPintosのおもちゃオペレーティングシステムに取り組んでいますが、GCC 4.6.2を使用すると奇妙なバグがあります。私がシステムコールの引数(インラインアセンブリーで3 pushl-sだけ)を押すと、いくつかの不思議なデータがスタックにも現れ、引数の順序が間違っています。 -fno-omit-frame-pointerを設定すると、奇妙なデータが取り除かれますが、引数の順序は変わりません。 GCC 4.5は正常に動作します。どのような特定のオプションがこれを修正できるのか?GCC 4.6.2の不思議なスタック問題

注:問題は引き続き-O0で発生します。

+3

最小のコード例? –

答えて

0

原因は、4.6.2以降でデフォルトで有効になっている-fomit-frame-pointerです。 -fno-omit-frame-pointerは問題を修正しました。

1

コード例と異なるコンパイルの結果の一覧がない場合は、手助けが困難です。しかし、ここにあなたの問題の3つの原因が考えられます:

  1. 引数がスタックにどのようにプッシュされるかを理解していることを確認してください。引数は後ろからプッシュされます。これにより、printf(char *, ...)は、最初の項目を調べて何個あるかを調べることができます。関数int foo(int a, int b, int c)を呼び出す場合は、cを、次にbを、最後ににプッシュする必要があります。
  2. スタック上の奇妙なデータが戻りアドレスまたはEFLAGSになることはありますか?私はPintosとシステムコールの仕組みについては分かりませんが、CALL/RETとINT/IRETの違いを理解していることを確認してください。 INTはフラグをスタックにプッシュします。
  3. インラインアセンブリに副作用がある場合は、その前にvolatile/__volatile__と記述します。さもなければGCCは最適化のときにそれを動かすことができます。

何が起こっているのかをよりよく理解するには、コードを確認する必要があります。

+0

パラメータは、3回のpushl-sとそれに続くシステムコール番号のプッシュ(asm volatile)で渡されます。しかし、カーネルセグメントがメモリを見るとき、引数は3 1 2オーダーです(あるいは、オプションによってはガベージさえあります)。 GCC 4.5では、適切な場所に、適切な順序で配置されています。 –

+0

@vahokifコード例を表示できますか?私はそれを解決できるかどうかは分かりませんが、コードを見てもほとんど不可能です。もちろん、コンパイラにバグがあることもあります。その場合、バグレポートを提出したいかもしれません。 –

0

syscallの後にスタックのパラメータを消去しましたか? gccは、スタックに触れ、コードを生成することが、期待したスタックポインタに依存していることを認識していないかもしれません。 -fno-omit-frame-pointer gccにロケートデータへのアクセスにe/rbpを使用させますが、実際の問題を隠すだけです。

関連する問題