[32ビット・システム] 関数呼び出し時のスタックの動きのメモ

32ビット・システムにおける関数呼び出し時のスタックの動きについて。こちらの記事でも書いた内容を改めてまとめ直した。 まずは関連用語の覚書 スタック関数の引数、関数内部のローカル変数や戻りアドレスが格納される。LIFO (Last In, First Out 後入れ先出し)。スタック領域はメモリの上位アドレスから下位アドレスに向かって確保されていく。スタック領域はプログラム実行時にコンパイラやOSによって自動的に割り当てられる。 ヒーププログラムの実行中に動的に確保されるメモリ領域。例えばmallocによって動的にメモリ領域を確保する場合は、ヒープ領域上に確保される。ヒープ領域はメモリの下位アドレスから上位アドレスに向かって確保されていく。 EIP次に実行する命令文のアドレスを格納している。命令文が実行されるたび、EIPの値は加算される (どのくらい加算されるかは実行された命令文のサイズによる) ESPスタック・ポインタ。スタック領域のトップに積まれたデータのメモリー・アドレスを格納する。スタックはメモリの上位アドレスから下位アドレスに向かって積み上がっていくので、ESPは最下位のアドレスに格納されたデータを指す。 EBPベース・ポインタ。データの格納領域の基点のメモリー・アドレスを格納する。通常、関数の最初において、EBPにはESPの値が設定される。これは関数の引数とローカル変数を追跡するためである。ローカル変数へのアクセスはEBPからオフセットを引くことによって行われる。関数の引数へのアクセスはEBPにオフセットを加算することによって行われる。※ただし、gccなどのGNUコンパイラは関数の引数・変数へのアクセスにEBPではなく、ESPを用いる。