1

ゲームプレイ バイナリの一部をその場でコンパイルするゲーム コード (ioquake3 プロジェクトから) があります (qvm システム)。現在、この操作の以前に保存されたバイナリをロードすることで、潜在的に高速化できます (ファイルの変更に関する予防措置が講じられています)。

ただし、これらのバイナリに保存された関数へのポインターは、セッションを通じて永続的ではありません。

その場でそれらを変更する適切な方法は何でしょうか? (メインアプリケーションで利用可能なアセンブラとアセンブリがあることを考慮してください)

4

2 に答える 2

2

これは、実行可能ファイルの通常のローダーが行うこととほとんど同じです。それらは通常、ファイルがロードされる場所に基づいて変更する必要があるアドレスへの参照がある場所のテーブルを保存することによって機能します。通常、それらはこれらの各場所に相対アドレスを格納するため、ファイルをロードするには、テーブルを見て、ベースロードアドレスをそれらの各アドレスにあるものに追加し、その結果をメモリにロードされるようにイメージに配置します。

于 2010-03-07T03:45:33.820 に答える
2

関連する関数ポインターのテーブルをパラメーターとして渡します。または、生成されたコードを、コードに対して相対的な固定位置に配置されたデータ領域に依存させることもできます。

このようなことをいじっていたとき、読み取り/書き込み/実行メモリ ページを設定し、前半を生成コードに使用し、後半をデータに使用したことを思い出します。制御を取得すると、コードは次のようになります。

call l
l:
pop eax ; eax has the current eip
and eax, 0fffff000h ;round down to the page size, 4K AKA 0x1000
add eax, 800h ;now eax points at the data area

...等々。

大規模に生成されたコードの場合、本格的な DLL として保存し、システム提供の再配置およびアドレス修正サービスを利用することができます。

于 2010-03-07T03:46:32.313 に答える