質問: 知恵袋1 知恵袋2 同じような質問を知恵袋でやっていますが(ルール違反承知の上で、こちらで解決したら向こう側も閉じます。) 図の画像など、私が分からない点を回答者さんへ伝えられないので teratailで質問させていただきます。 尚、知識がまだ前提で躓いているレベルです。 OSの仕組みに興味を持ち、参考書を読んでいます。 その中で・・・ セグメンテーションについて解説されていました。 - - 状況としては **データセグメント・コードセグメント・スタックセグメント・テキストセグメント** **などのメモリセグメント(?)** **セグメント方式・ページング方式という仮想メモリを実現するにあたって、どうやって物理メモリと仮想メモリをどうやって扱うか のやつ** **どっちも”セグメント”がついているけど、お互い関係あるの?** **で、悩んでいる段階です。** wikiでググると、”セグメンテーション”はないけど”セグメント方式”は出てくる。 だから、・・・セグメンテーション==セグメント方式(???) - - ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/f5624d3cbc41642743743888e6957d3c.png) ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/74f58be47ecf80a9b26277225d0d0207.png) (そもそも、前提から理解できていないけれど・・・) この上記の図はメモリセグメントを表しています。 ここで、疑問なのは メモリセグメントというのは 物理アドレスを コード・データ・スタック などなどの領域にぶった切ってから プロセスにそれぞれの領域を1つずつ渡していくのですか? 図がプロセスに割り当てられたメモリだけを示しているのか それとも、 メモリ全体を示しているかでかなり解釈が変わってくると思うのですが・・・ - - もしくは・・・ プロセスがOSから渡された、連続に並んで見える仮想アドレスを プロセスが勝手にメモリセグメントの領域を決めるんですか? (うまく伝えずらいですが・・・) 分からないので教えてください。 言い方表現で誤っているところ・何を言っているのかわからかったら 修正依頼お願いします・・・。 ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/5bfcfe5bc0785fb2a6438ce514111955.png) ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/3bf96b09ea7a89747aa398879d8f4a7f.png) ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/4bf4bf095d3c46f7998c61cdc3fcb083.png) ![イメージ説明](https://teratail-v2.storage.googleapis.com/uploads/contributed_images/b9c12064fad02745c11d69388df78010.png) 0から作るOS開発 Vol.1 ブートローダー編 0から作るブートローダー
回答: セグメントというのは「部分」だと思ってください。メモリ全体の中の「部分」のことを、セグメントという分け方で考えています。 これを説明するには、現在の Intel x86 プロセッサの始祖である 8086 プロセッサに(さらにその前身たる 8085 まで)遡らねばなりません。 Intel は 8080 プロセッサとそのマイナーアップデートとも言うべき 8085 プロセッサにより、8bit CPU の分野で2強の位置を築きました(対抗としては 6809, あと Intel 互換の Z-80 など)。そして次世代 CPU として、16bit の 8086 の開発を行います。 8086 は 8bit CPU とは違い、メモリ空間が大幅に増強(64KB → 1MB)されました。が、プログラムを作る側としては、8080/8085 からすんなりと移行してもらいたい。そのため、「8080 のアセンブリソースを再アセンブルするだけで 8086 に対応できるようにする」という手段に出ます。 このためにアドレスは 64KB に限定されることになってしまいました。(あくまでも8080/8085 互換ソースの場合) 64KB のアドレッシングで、1MB のメモリ空間を十全に使うためにどうするか。その回答が「セグメント」の導入です。 セグメントという「1MB の中のどの64KB の部分かを示す」ものを追加することで、必要ならば1MBの空間をフルに使いながらも、コードレベルでは64KBのアドレッシングのみで済ませられるようにしたのです。 これを実現したのが 8086 のセグメントレジスタです。セグメントレジスタはコード用、データ用、スタック用、汎用の4個(CS,DS,SS,ES)用意され、これにより「コードとデータの分離」も可能となりました。 さて、16bit CPU が広まっていくと、大型コンピュータにあった特権方式の保護といった高度な(OSに必須な)機能が CPU で実装されるようになってきます。それが 80286 から始まる「プロテクトモード」です。プロテクトモードでは資源を仮想化する(物理と論理を切り離す)ことによる保護が行われるようになっており、Intel は 80286 においてセグメントの定義を変更することでこの仮想化を実現したのです。 プロテクトモードにおいてはセグメントレジスタはメモリアドレスを直接表すのではなく、メモリ空間の情報を格納しているセグメントディスクリプタという領域へのポインタとなっています。 セグメントディスクリプタが「論理アドレス 0x00400000~の1MB」を表していたとして、それが物理的なメモリアドレスのどこに該当するのかは、メモリ管理ユニット(MMU)以外知っている必要がありません。もしかしたら物理メモリが割り当てられていない場合もありえます。 そのような場所にアクセスが発生したら、MMU が割当たっていないことを検知して、新しくメモリを割り当てます。物理メモリに空きがなければ、使う頻度の低い他のセグメントに割り当たっていたメモリを(HDD にデータを退避させるなどして)解放して割り当て直します。(メモリのスワップといわれるものです) そして32bit CPU になると、わざわざセグメントでメモリ空間を分けずに、32bit のフラットなメモリ空間を一つのセグメントに割り当てる(=フラットメモリモデル)のが常態化します。ここに至ってセグメントの意味は(コードとデータの分離と保護、及びメモリの仮想化の二つ以外)なくなったといってよいのです。