x86 環境でこれを行うことについて話している場合、不可能ではないはずです。ただし、x86 命令は可変長であるため、注意して使用する必要があります。長い命令は後続の命令を上書きする可能性があり、短い命令は上書きされた命令の残りのデータを残し、ノープする必要があります (NOP 命令)。
x86 が最初に保護されたとき、インテルのリファレンス マニュアルでは、XO (実行のみ) 領域へのアクセスをデバッグするために次の方法を推奨していました。
- 新しい空のセレクターを作成します (far ポインターの「高い」部分)
- その属性を XO 領域の属性に設定します
- その内容のみを確認したい場合は、新しいセレクターのアクセス プロパティを RO DATA に設定する必要があります。
- データを変更する場合は、アクセス プロパティを RW DATA に設定する必要があります
したがって、問題の答えは最後のステップにあります。デバッガーが行うブレークポイント命令を挿入できるようにする場合は、RW が必要です。80286 よりも新しいプロセッサには内部デバッグ レジスタがあり、ブレークポイントが発行される可能性がある非侵入型監視機能を有効にします。
Windows は、Win16 以降、これを行うためのビルディング ブロックを利用できるようにしました。それらはおそらくまだそのままです。Microsoft は、このクラスのポインター操作を「サンク」と呼んでいると思います。
私はかつて、DOS 用の PL/M-86 で非常に高速な 16 ビット データベース エンジンを作成しました。Windows 3.1 (80386s 上で動作) が登場したとき、私はそれを Win16 環境に移植しました。利用可能な 32 ビット メモリを利用したかったのですが、利用可能な PL/M-32 (または Win32) がありませんでした。
私のプログラムが次の方法でサンクを使用した問題を解決するために
- 構造体を使用して定義された 32 ビット far ポインター (sel_16:offs_32)
- グローバル メモリを使用して 32 ビット データ領域 (<=> >64KB サイズ) を割り当て、それらを 16 ビット far ポインタ (sel_16:offs_16) 形式で受信
- セレクターをコピーして構造体にデータを入力し、16 ビットの乗算と 32 ビットの結果を使用してオフセットを計算します。
- 命令サイズオーバーライドプレフィックスを使用して、ポインター/構造体を es:ebx にロードしました
- 命令サイズとオペランド サイズのプレフィックスの組み合わせを使用してデータにアクセスした
メカニズムにバグがなくなると、問題なく機能しました。私のプログラムが使用した最大のメモリ領域は 2304*2304 の倍精度で、約 40MB になりました。今日でも、これを「大きな」メモリ ブロックと呼んでいます。1995 年には、典型的な SDRAM スティック (128 MB PC100) の 30% でした。