スタックダンプの読み方

レジスタのEBPを基準にして読み解いていきます。EBPで示されるアドレスの手前4バイトが呼び出し元アドレス、EBP以降が引数です。EBPで示される場所に格納されている4バイトが関数呼び出し前のEBPアドレスです。
EBPが0x00C00018の場合を例としてスタックを読み解きます。

0x00C00010 : 00 00 00 04 // 引数、または、スタック変数
0x00C00014 : 00 00 00 03 // 引数、または、スタック変数
0x00C00018 : 00 C0 00 28 // 手前のEBPアドレス
0x00C0001C : 00 40 10 40 // 呼び出し元アドレス
0x00C00020 : 00 00 00 02 // 引数、または、スタック変数
0x00C00024 : 00 00 00 01 // 引数、または、スタック変数
0x00C00028 : 00 C0 00 40 // 手前のEBPアドレス
0x00C0002C : 00 40 10 80 // 呼び出し元アドレス

cdecl呼び出し規約や、stdcall呼び出し規約では、引数は右に書かれているものから順にスタックに格納されます。したがってアドレスの大きいものから順に、右から左の引数となります。Pascal呼び出し規約では逆に左から順に格納されます。
C++の場合this ポインタがスタックに追加されます。thisポインタはすべての引数をスタックに格納した後、最後にスタックに積まれます。Windowsでは関数が引数を伴わない場合には、thisポインタをスタックに積まずに、ECXレジスタに格納して関数を呼び出す場合があります。
スタック変数の積まれる順序は保障されません。最適化の結果、順不同にスタックに積まれます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です