それで、私はコンピューター・アーキテクチャーのクラスに必要なため、少しのアセンブリーを学ぼうとしています。フィボナッチ数列の印刷など、いくつかのプログラムを作成しました。
関数を書くときはいつでも、次の3行を使用することを認識しました(gcc
から生成されたアセンブリコードをそのC
に相当するものと比較して学んだように):
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
私はそれについて2つの質問があります:
%rbp
を使用する必要があるのですか?その内容は2行目の%rsp
に移動されるため、%rbp
を使用する方が簡単ではありませんか?%rsp
から何かを差し引く必要があるのはなぜですか?つまり、常に16
であるとは限りません。7または8個の変数のようにprintf
ingした場合、24
または28
を減算します。仮想マシン(4 GB RAM)、Intel 64ビットプロセッサでManjaro 64ビットを使用しています
rbp
は、x86_64のフレームポインターです。生成されたコードでは、スタックポインター(rsp
)のスナップショットを取得するため、rsp
に調整が行われると(つまり、ローカル変数またはPush
ing値をスタックに予約します) )、ローカル変数と関数パラメーターは、rbp
からの一定のオフセットからアクセスできます。
多くのコンパイラは、最適化オプションとしてフレームポインターの省略を提供しています。これにより、代わりにrsp
に関連する生成されたアセンブリコードアクセス変数が作成され、関数で使用する別の汎用レジスタとしてrbp
が解放されます。
GCCの場合、AT&Tアセンブラ構文から使用していると思いますが、そのスイッチは-fomit-frame-pointer
です。そのスイッチでコードをコンパイルしてみて、どのアセンブリコードを取得するかを確認してください。 rsp
の代わりにrbp
に関連する値にアクセスすると、ポインターからのオフセットが関数全体で異なることに気付くでしょう。