C コンパイルされたプログラムはどのセグメントを使用しますか?

StackOverflow https://stackoverflow.com/questions/2754295

  •  02-10-2019
  •  | 
  •  

質問

OSDev wiki で読んだのですが、x86 アーキテクチャの保護モードでは、コードとデータに別々のセグメントを作成できる一方で、コード セクションに書き込むことはできないとのことです。Windows (はい、これがプラットフォームです) が新しいコードをコード セグメントにロードし、データがデータ セグメント上に作成されます。しかし、この場合、プログラムはセグメントをデータ セグメントに切り替える必要があることをどのようにして知るのでしょうか?私の理解が正しければ、記述子を切り替えない限り、すべてのアドレス命令はコードを実行するセグメントを指しているからです。しかし、このようにまとめられたフラット メモリ モデルにより、1 つのセグメント内でコードとデータを実行できるという記事も読みました。しかし、私はこれをアセンブラに関連してのみ読みました。それでは、Windows 上で C コンパイルされたコードの場合はどうなるでしょうか?ありがとう。

役に立ちましたか?

解決

には2つの意味があります セグメント 説明では:

  • 8086 メモリ アドレス セグメント
  • オブジェクトモジュールプログラムセクションセグメント

1 つ目は、80386+ セグメント レジスタにロードされる内容に関連します。これには、物理​​メモリの開始アドレス、メモリ割り当ての長さ、許可された読み取り/書き込み/実行アクセス、および低から高またはその逆に増加するかどうか (さらに、「参照上のコピー」などのいくつかのあいまいなフラグ) が含まれます。

2 番目の意味は、オブジェクト モジュール言語の一部です。基本的に、という名前のセグメントがあります code, という名前のセグメント data (初期化されたデータを含む)、およびという名前の初期化されていないデータのセグメント bss (1960 年代のアセンブラの擬似命令にちなんで命名されました。 記号で始まるブロック)。リンカがオブジェクト モジュールを結合するとき、すべてのコード セグメントをまとめて配置し、すべてのデータ セグメントを別の場所にまとめて配置し、BSS もまとめて配置します。ローダーはメモリ アドレスをマップするときに、合計コード領域を調べて、少なくともそのサイズの CPU メモリ割り当てを割り当て、セグメントをコードにマップするか (仮想メモリの状況で)、割り当てられたメモリにコードを読み取ります。メモリを一時的にデータ書き込み可能に設定する必要があります。書き込み保護は、CPU のページング メカニズムおよびセグメント レジスタを通じて行われます。これは、たとえば、誤ったデータ アドレスによるコード書き込みの試みを保護するためです。ローダーは、2 つのデータ セグメント グループに対しても同様のセットアップを実行します。(その他に、スタックセグメントの設定と割り当て、共有イメージのマッピングがあります。)

x86 で命令を実行する限り、各オペランドには関連するセグメント レジスタがあります。これらは明示的な場合もあれば、暗黙的な場合もあります。コードは暗黙的にアクセスされます。 CS, 、積み重ねる SS それは常に暗示されます ESP または EBP レジスターが関係しており、 DS 他のほとんどのオペランドに対して暗黙的に指定されます。 ES, FS, 、 そして GS などの一部の文字列命令を除き、他のすべての場合にオーバーライドとして指定する必要があります。 movs そして cmps. 。フラット モデルでは、すべてのセグメント レジスタが同じアドレス空間にマップされますが、CS では書き込みが許可されません。

最後の質問に答えると、CPU には、プロセスのフラットな仮想メモリ空​​間にアクセスするために一度にセットアップされた 4 つ (またはそれ以上) のセグメント レジスタがあります。各オペランド アクセスは、命令に適切であるかどうかチェックされます (オペランドをインクリメントしないなど)。 CS アドレス)、ページング保護ユニットによって許可されているかどうかもチェックされます。

他のヒント

あなたが読んだ情報は時代遅れです。 Windowsバージョン〜1993以来、フラット32ビット仮想メモリスペースを使用しています。 CSおよびDSセグメントの値は、もはや重要ではなく、変更することはできません。現在、メモリページの属性によって実装されているコードとデータの概念がまだあります。 flnewprotectの引数で渡された許可された値を確認する VirtualProtectex()API関数.

このAPIを自分で使用することはほとんどありません。属性は、実行可能な画像ローダーとHeap Managerによって設定されます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top