0

プログラム カウンター (AKA 命令ポインター) を 0 にリセットしようとしています。

次の C コードが動作することを期待していました (しかし、動作しませんでした)。

typedef void(*func)();
func reset = NULL;
reset();

VS2013 コンパイラを使用する場合の逆アセンブリは次のとおりです。

mov  dword ptr[reset],0
mov  esi,esp
call dword ptr[reset]

この問題は C 言語の標準ではなく、特定のコンパイラの実装の問題であることを認識しています。それにもかかわらず、私はそれがすべての適切なコンパイラでほとんど機能することを期待しています.

PC/IP をその関数のアドレスに設定する以外に、関数呼び出しを何にコンパイルできますか?

ありがとう

4

1 に答える 1

1

ターゲットとするハードウェアに大きく依存しますが、おそらく他の関数ポインター呼び出しと同じものにコンパイルされます。コンパイラが に与えられた定数値を認識し、そのresetように最適化することも可能です。他に何もなければ、いつでもできる:

((void (*)())NULL)();

NULL基本的に type のパラメーターなしの関数にキャストしますvoid


呼び出しが成功するかどうかは、まったく別の問題です。仮想メモリを使用するほとんどのプラットフォームでは、カーネルは意図的にNULLアドレス + マップされていない領域 (おそらく数 KB、おそらく数 MB) を残します。命令ポインターはおそらく 0 になりますが、CPU がそのアドレスから命令をフェッチしようとするとすぐにKABOOM .

于 2014-08-13T18:03:44.440 に答える