web-dev-qa-db-ja.com

x86_64アセンブラーのRBPレジスタの目的は何ですか?

それで、私はコンピューター・アーキテクチャーのクラスに必要なため、少しのアセンブリーを学ぼうとしています。フィボナッチ数列の印刷など、いくつかのプログラムを作成しました。

関数を書くときはいつでも、次の3行を使用することを認識しました(gccから生成されたアセンブリコードをそのCに相当するものと比較して学んだように):

pushq   %rbp
movq    %rsp, %rbp
subq    $16, %rsp

私はそれについて2つの質問があります:

  1. まず、なぜ%rbpを使用する必要があるのですか?その内容は2行目の%rspに移動されるため、%rbpを使用する方が簡単ではありませんか?
  2. %rspから何かを差し引く必要があるのはなぜですか?つまり、常に16であるとは限りません。7または8個の変数のようにprintfingした場合、24または28を減算します。

仮想マシン(4 GB RAM)、Intel 64ビットプロセッサでManjaro 64ビットを使用しています

42
user6827707

rbpは、x86_64のフレームポインターです。生成されたコードでは、スタックポインター(rsp)のスナップショットを取得するため、rspに調整が行われると(つまり、ローカル変数またはPushing値をスタックに予約します) )、ローカル変数と関数パラメーターは、rbpからの一定のオフセットからアクセスできます。

多くのコンパイラは、最適化オプションとしてフレームポインターの省略を提供しています。これにより、代わりにrspに関連する生成されたアセンブリコードアクセス変数が作成され、関数で使用する別の汎用レジスタとしてrbpが解放されます。

GCCの場合、AT&Tアセンブラ構文から使用していると思いますが、そのスイッチは-fomit-frame-pointerです。そのスイッチでコードをコンパイルしてみて、どのアセンブリコードを取得するかを確認してください。 rspの代わりにrbpに関連する値にアクセスすると、ポインターからのオフセットが関数全体で異なることに気付くでしょう。

37
Govind Parmar