PC マップ例外
Mac OS X アプリケーション開発 への移動
Mac システムと Linux システムでは、プログラム カウンタ(PC)でマップされた例外を使用するのに対して、Windows(Win32)では、スタック上でリンクされた登録レコードを使用します。
アセンブリ ルーチンの巻き戻し
アセンブリ ルーチンでは例外を捕捉できません。そのうえ、巻き戻しの特性のため、アセンブリ ルーチンを呼び出す際には注意する必要があります。アセンブリ以外のコードでアセンブリ コードを呼び出し、そのアセンブリ コードで今度はアセンブリ以外のコードを呼び出すという場合には、この点は重要です。例外が発生する(送出される)と、スタック アンワインダはその例外から渡されるスタック フレームを破棄します。アンワインダ プロセスは、各種の重要なレジスタを元に戻す必要があります。それらの中には、スタック ポインタやフレーム ポインタなどがあります。このようなアンワインダ プロセスが不可能になるようなことをアセンブリ コードで行うことは可能であり、そのようなことを行わないようにする必要があります。重要な点の 1 つは、スタック ポインタを不定量だけ変更すると、アンワインダは独力でフレームを巻き戻すことはできないということです。以下に例を示します。
sub esp, eax
または
sub esp, 0xF
and esp, 0xFFFFFFF0
上記のアセンブリ コードの場合はどちらも、与えられた手続きをアンワインダが巻き戻すことはできません。このような命令を含んだ手続きをアンワインダが巻き戻せるようにするには、以下のように、コードにスタック フレームを含める必要があります。
push ebp
mov ebp, esp
コードの最初の 2 つの命令は、スタック フレームの作成でなければなりません。アセンブリ コードがコンパイルされるときに、この命令シーケンスがコンパイラにより認識され、コンパイラがそのルーチン専用の巻き戻し情報を生成します。フレームが存在しなければ、例外が発生した(送出された)場合に変更を巻き戻すために、コンパイラはアセンブリ ルーチン全体を調べて、コードでスタックがどのように変更されているかを分析しようとします。