私たちはMIPSアセンブラを研究しています(この質問は一般的にアセンブリにも当てはまると思います)。先生はのに私たちを紹介しました。フレームポインタの利点は何ですか?
addiu $sp, $sp, -8 ; alloc 2 words in the stack
sw $s0, 4($sp) ; save caller function $s0 value in the stack
sw $ra, ($sp) ; save the return address for the callee function
と関数エピローグで:私は関数プロローグを持っている場合は
は、私が直接スタックポインタを行うために使用
move $v0, $0 ; set 0 as return value
lw $s0, 4($sp) ; pick up caller $s0 value from the stack
lw $ra, ($sp) ; pick up return address to return to the caller
addiu $sp, $sp, 8 ; dealloc the stack words I used
jr $ra ; return back to caller
教師は、フレームポインタを使用することがあると言いました組み立て時に関数を書くときに私たち人間に有益です。
addiu $sp, $sp, -12 ; alloc 3 words in the stack
sw $fp, 8($sp) ; save caller frame pointer in the stack
addiu $fp, $sp, 8 ; set $fp to the uppermost address of the activation frame
sw $ra, -4($fp) ; saving like the first example, but relative
sw $s0, -8($fp) ; to the frame pointer
教師はまた、スタックポインターが他のスペースを割り振ることがあり、我々が注意を払う必要があるので、関数内のアクティベーションフレームを参照することがより困難であると述べました。 フレームポインタを使用すると、アクティブ化フレームへの静的ポインタがあります。
はい、でも、は、呼び出し元関数の保存されたデータだけを含んでいるので、関数内でのアクティベーションを使用する必要がありますか?
私は実装するのが難しいと思っています。フレームポインタがプログラマにとって大きな利点となる本当の実用的な例はありますか?
フレームポインタを使う必要がない多くの命令セットでは、コンパイラ作成者のデバッグが簡単になりますが、実際には有効な言い訳ではありません。 gccなどを使用すると、そのオーバーヘッドを保存するために、フレームポインタを使用しないで、それを使用するビルドコードを使用しないことを選択できます。いくつかの既定値と既定値なし。関数内のオフセットをその関数に固定します。変数Xはその関数に対して常にfp-Nです。あなたは関数全体に対してX sp + Mを作ることができます。あるいは関数が進むにつれて、スペースを節約するために必要に応じてspを動かすことができます。 –
しかし、一日の終わりに、教師の言うことは何でも、そのクラスのために、クラスを渡し、すべてを疑い、あなたがそれを信じているかどうかを見るためにそれを発見する。先生の宿題を簡単にすることができたのか、それともこのプログラミングルールは実際には単語の意味で「より良い」と教えられたのでしょうか?私はそれが人間にとってはより簡単になると思っていますが、同時にコンパイラや人間では、spを動かして関数のすべての使い方をカバーすると、フレームポインタがなければ同じように簡単です。 –
これを試してください:5つ以上のフィールドを使って、あなたの頭にC構造を定義してください。スタックのためのスペースを割り当てます。それを初期化する。スタック上のパラメータとしてメンバを他の関数に渡します。それはフレームポインタの有無にかかわらず行います。 –