x86カルトクイズ

光成さんとこのに、Q8のみ解答してみる。
久しくアセンブラで書いていないので、速攻で正答がわかるのがこれしかなかったのだが。

解答

  • 32bitのWindows用のEXEをVCで作成する場合を想定し、リンカのオプションがデフォルトだとすると、このコードは、スタック領域が足りていても、アクセス違反例外を生成する可能性がある。

説明

  • EXEの起動時、スタック用領域としてのメモリを予約するが*1、この時点でコミットするのは上位側の一部のページのみ*2
  • 実行時、予約済未コミットの領域を、以下のようにコミットする。
    • esp がコミット済スタックの最下位ページを指している状態で [esp] へのアクセスがあると、予約済未コミットのページから4KB単位でコミットする。
    • 上記コミット以外でのコミットは行われない。
    • 予約済未コミットの残りが4KB以下だと上記コミットは行われないが*3、今回はスタック領域が足りている前提なので、その場合を考慮しない。
  • したがって、Q8の sub esp, 8192 の実行後、espはスタック領域の中ではあるが未コミットのメモリを指している可能性がある。その場合、mov [esp], eax を実行すると、アクセス違反例外が発生する。
  • スタック領域の下位側に隣接しているページに上書きしてしまう可能性にも言及すべき?
  • 文章で書くとわかりづらいので、より詳細は、ADVANCED WINDOWS (マイクロソフトプレスシリーズ)の207〜209ページの図を参照。

*1:リンカのオプションがデフォルトの場合、1MB

*2:リンカのオプションがデフォルトの場合、8KB

*3:つまり、リンカのオプションがデフォルトの場合に、実際にスタックとして使えるのは、1MB-4KB