このアプローチは通常、中間バイトコード表現(Java、.netなど)を使用する環境で使用されます。バイトコードには十分な「高レベル」構造(マシンコードよりも高レベルの高レベル)が含まれているため、VMはバイトコードからチャンクを取り出して、コンパイルされたメモリブロックに置き換えることができます。コンパイル自体は複雑で時間のかかるプロセスであるため、VMは通常、コードがすでに解釈された回数をカウントすることによって、どの部分がコンパイルされるかを決定します。したがって、何度も実行される部分のみをコンパイルすると便利です。
しかし、どのようにしてオペコードを読み取り、そのコードを生成するのでしょうか。
オペコードのスキームはVMの仕様によって定義されるため、VMはプログラムファイルを開き、仕様に従って解釈します。
その人は事前に作成されたアセンブリチャンクを持っていて、それらを一緒にコピー/バッチ処理する必要がありますか?アセンブリはCで書かれていますか?
このプロセスはVMの実装の詳細であり、通常、VMオペコードストリームをマシンコードに変換できるコンパイラが組み込まれています。
システム割り込みをどのように説明しますか?
非常に単純です:なし。VM内のコードは、実際のハードウェアと対話できません。VMはOSと対話し、解釈されたコード内の特定の部分をジャンプ/呼び出して、OSイベントをコードに転送します。コード内またはOSからのすべてのイベントは、VMを通過する必要があります。
また、ハードウェア仮想化製品は、ある種のJITを使用できます。X86の世界での一般的な使用例は、16ビットのリアルモードコードを32ビットまたは64ビットのプロテクトモードコードに変換して、リアルモードでCPUをエミュレートするように強制されないようにすることです。また、ソフトウェアのみのVMは、実行中のコードのジャンプ命令をVM制御ソフトウェアにジャンプすることで置き換えます。VM制御ソフトウェアは、各分岐でジャンプ命令の次のコードパスをスキャンし、実際のコードの宛先にジャンプする前に置き換えます。しかし、ジャンプ置換がJITコンパイルとして適格であるかどうかは疑問です。