自分用メモ
以下のプログラムでx86における関数呼び出し時のスタックの使い方
start: // ... push 3 push 2 push 1 call func // func(1,2,3) sub esp, 12 // ... func: push ebp mov ebp, esp // -- 関数の処理 -- mov esp, ebp //espの復元 pop ebp // ebpの復元 ret
1.スタックに積まれる順番
1.引数
2.リターンアドレス
3.退避されたebp
退避されたebpの次(スタックの先頭方向)にはローカル変数が格納される。
2.引数について
pushされる順番
arg3,arg2,arg1の順でpushされる。
関数内での引数へのアクセス
[ebp+8] : 第一引数
[ebp+12] : 第二引数
[ebp+16] : 第三引数
(以下省略)
3.ローカル変数について
ローカル変数の確保
関数内で以下の命令が実行される。
sub esp, 4 * (確保するローカル変数の個数)
ローカル変数の破棄
ret命令直後、つまりcall命令の次のデータ列で以下の命令が実行される。
add esp, 4 * (確保するローカル変数の個数)
関数内でのローカル変数へのアクセス
4.その他
leave命令は以下と等価
mov esp,ebp pop ebp
enter命令は以下と等価
push ebp mov ebp,esp sub esp,N