特に、呼び出し元が保存したレジスタと呼び出し先が保存したレジスタのコード内の変数に対して実行された保存/復元操作の数をどのように知ることができますか?
2 に答える
揮発性レジスターとも呼ばれる呼び出し元保存レジスターは、呼び出し元関数がレジスター内の値を必要とする場合に、呼び出し元関数が (通常はランタイム スタックに) 保存する必要がある任意の CPU コア レジスターです。つまり、値が「ライブ」の場合。呼び出し先保存レジスタ (不揮発性レジスタとも呼ばれます) は、関数が破棄しないことを約束する必要がある値を含む任意の CPU コア レジスタです。呼び出し先 (呼び出された関数) がこれらのレジスタを使用する必要がある場合、最初にそれらのレジスタ (通常はランタイム スタック上) に値を保存し、呼び出し元に戻る前にそれらを復元する必要があります。
Carl Norum が言及しているように、どの CPU コア reg が caller-save であり、どれが callee-save であるかは、呼び出し規則 (歴史的に不十分に文書化され、歴史的にコンパイラ固有) によって定義されるか、ABI (アプリケーション バイナリ インターフェイス) によって定義されます。
その情報は明らかに x86 固有のものですが、Agner Fog による次のドキュメントでは、呼び出し規則と呼び出し元保存/呼び出し先保存レジスタについて非常によく説明されています。
http://www.agner.org/optimize/calling_conventions.pdf
以下は、呼び出し規約を含む PowerPC EABI について説明しています。ただし、このドキュメントでは、「volatile」と「nonvolatile」を検索してください (それぞれ caller-save と callee-save)。
http://www.freescale.com/files/32bit/doc/app_note/PPCEABI.pdf
物理的には、呼び出し元保存レジスタと呼び出し先保存レジスタの間に違いはありません。この区別は、プロシージャ コールの標準 (呼び出し規約) または ABI によってのみ行われます。コードの一部を分析する必要がある場合は、ABI または呼び出し規約のマニュアルを参照として使用して、コードをコンパイル (ただし、アセンブルはしない) またはバイナリを逆アセンブルして、関数ごと、命令ごとに調べることができます。