私は 32 ビット OS を開発しており、ELF ローダーを実装しました。実行可能ファイルをロードできますが、プログラムを実行して、それぞれに独自のデータ セグメントを持たせたいと考えています。32ビット保護モードでの調査から収集したものから、データセグメントは64kブロックを参照していますか? DS を 16 に設定し、mov dword eax,[test] のようなコードがあったとします。プロセッサは、(DS * 0xFFFF) + test right? のようなテスト中のものを取得します。したがって、test が 0 の場合、実際に読み取られるアドレスは 983025 または 0xEFFF1 でしょうか? これは正しいですか、それとも私は完全にオフですか
1 に答える
独自の OS を開発しているので、データ セグメント、コード セグメント、およびスタック セグメントは、ほとんど好きなものにすることができます。
386 個の PE セグメント レジスタでは、物理メモリに存在する記述子テーブルを「ポイント」し、各セグメントに 8 バイト (または x64 では 16 バイト?) が割り当てられ、ベース アドレス、読み取り/書き込み/実行フラグ、およびセグメント サイズを定義します。 .
通常、これらの制限は 0 および 2^32(-1) として設定され、フラット モードとも呼ばれます。
linux/cygwin などに準拠した gcc を使用している場合でも、各メモリ アクセスがベース レジスタに応じてデフォルトのセグメントを使用することを知っていると、セグメント化されたアーキテクチャの恩恵を受ける可能性は十分にあります。mov [ebp + ... ]
またはベース レジスタとしてすべてのローカル変数にアクセスする限りmov [esp + ...]
、スタック セグメントが使用されます。これを例外処理で使用して、スタックの破損とヒープの破損を区別できます。自動的に成長するデータ/スタックセグメントなどに利用できます。アプリケーションに分離されたデータ領域を提供するために使用できます-おそらく、セグメンテーションを通じてメモリマップファイルAPIを実装できます-Linuxとは対照的に、 fs: と gs: はカーネル用に予約されています。