プロローグとエピローグ コードを記述するときの考慮事項
Microsoft 固有の仕様 →
独自のプロローグとエピローグを記述する前にシーケンスようなスタック フレームがどのように配置されるかを理解することが重要コードします。理解することも有用 __LOCAL_SIZE 記号を使用する方法を示します。
スタック フレーム レイアウト
この例では32 ビット関数に表示される標準プロローグ コードです :
push ebp ; Save ebp
mov ebp, esp ; Set stack frame pointer
sub esp, localbytes ; Allocate space for locals
push <registers> ; Save registers
localbytes の変数をローカル変数にはスタックに必要なバイト数を表し <registers> の変数はスタックに格納するレジスタの一覧を表すプレースホルダーです。登録をクリックした後スタックに他の適切なデータを配置できます。次に対応するエピローグ コードです :
pop <registers> ; Restore registers
mov esp, ebp ; Restore stack pointer
pop ebp ; Restore ebp
ret ; Return from function
スタックは常に増加します (最高からに (下位メモリ アドレスに)。ebp にプッシュされた値へのベース ポインター ()ebp のポインター。ローカル エリアは ebp-4 から始まります。ローカル変数にアクセスするにはebp から適切な値を減算してebp からのオフセットを計算します。
__LOCAL_SIZE
コンパイラは関数プロローグのインライン アセンブラー コード ブロックを使用してシンボル __LOCAL_SIZE を提供します。このシンボルをカスタム プロローグ コードのスタック フレーム内のローカル変数の領域を割り当てるために使用されます。
コンパイラは __LOCAL_SIZE の値が決まります。この値はすべてのユーザー定義のローカル変数とコンパイラにより生成された一時変数の合計バイト数です。__LOCAL_SIZE は即値オペランドとしてのみ使用できます。; この場合は式では使用できません。このシンボルの値を変更するか定義し直す必要があります。次に例を示します。
mov eax, __LOCAL_SIZE ;Immediate operand--Okay
mov eax, [ebp - __LOCAL_SIZE] ;Error
カスタム プロローグとエピローグを含む生の関数の使用例を次に示します __LOCAL_SIZE プロローグのシーケンスのシンボルの配列を示しています :
// the__local_size_symbol.cpp
// processor: x86
__declspec ( naked ) int main() {
int i;
int j;
__asm { /* prolog */
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
}
/* Function body */
__asm { /* epilog */
mov esp, ebp
pop ebp
ret
}
}