PC マップ例外

提供: RAD Studio
移動先: 案内検索

MacOS アプリケーション開発 への移動


Mac および Linux のシステムではプログラム カウンタ(PC)でマップされた例外を使用しますが、Windows(Win32)ではスタック上でリンクされた登録レコードを使用します。

アセンブリ ルーチンのアンワインド

アセンブリ ルーチンでは例外を捕捉できません。 そのうえ、アンワインドの特性のため、アセンブリ ルーチンを呼び出す際には注意する必要があります。 アセンブリ以外のコードでアセンブリ コードを呼び出し、そのアセンブリ コードで今度はアセンブリ以外のコードを呼び出すという場合には、この点は重要です。 例外が発生する(送出される)と、スタック アンワインダはその例外から渡されるスタック フレームを破棄します。 アンワインダ プロセスは、各種の重要なレジスタを元に戻す必要があります。 それらの中には、スタック ポインタやフレーム ポインタなどがあります。 このようなアンワインダ プロセスが不可能になるようなことをアセンブリ コードで行うことは可能であり、そのようなことを行わないようにする必要があります。 重要な点の 1 つは、スタック ポインタを不定量だけ変更すると、アンワインダは独力でフレームをアンワインドすることはできないということです。 例:

sub esp, eax

or

sub esp, 0xF
and esp, 0xFFFFFFF0

上記のアセンブリ コードの場合はどちらも、与えられた手続きをアンワインダがアンワインドすることはできません。 このような命令を含んだ手続きをアンワインダがアンワインドできるようにするには、以下のように、コードにスタック フレームを含める必要があります。

push ebp
mov ebp, esp

コードの最初の 2 つの命令は、スタック フレームの作成でなければなりません。 アセンブリ コードがコンパイルされるときに、この命令シーケンスがコンパイラにより認識され、コンパイラがそのルーチン専用のアンワインド情報を生成します。 フレームが存在しなければ、例外が発生した(送出された)場合に変更をアンワインドするために、コンパイラはアセンブリ ルーチン全体を調べて、コードでスタックがどのように変更されているかを分析しようとします。