質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

Q&A

解決済

5回答

6864閲覧

セグメンテーションとは何なのか。セグメントとは?単語の意味から混乱しています。

kazuyakazuya

総合スコア193

OS

OS(オペレーティングシステム)は、システムソフトウェアの一種であり、一般的に、ハードウェアを直接的に管理・操作する最も中心的な機能を有するソフトウェアがオペレーティングシステムとして呼ばれます。

0グッド

1クリップ

投稿2019/11/18 13:41

編集2019/11/20 02:10

知恵袋1
知恵袋2
同じような質問を知恵袋でやっていますが(ルール違反承知の上で、こちらで解決したら向こう側も閉じます。)

図の画像など、私が分からない点を回答者さんへ伝えられないので
teratailで質問させていただきます。

尚、知識がまだ前提で躓いているレベルです。

OSの仕組みに興味を持ち、参考書を読んでいます。

その中で・・・

セグメンテーションについて解説されていました。

--
状況としては

データセグメント・コードセグメント・スタックセグメント・テキストセグメント
などのメモリセグメント(?)
セグメント方式・ページング方式という仮想メモリを実現するにあたって、どうやって物理メモリと仮想メモリをどうやって扱うか のやつ
どっちも”セグメント”がついているけど、お互い関係あるの?
で、悩んでいる段階です。

wikiでググると、”セグメンテーション”はないけど”セグメント方式”は出てくる。

だから、・・・セグメンテーション==セグメント方式(???)

--

イメージ説明

イメージ説明

(そもそも、前提から理解できていないけれど・・・)

この上記の図はメモリセグメントを表しています。

ここで、疑問なのは

メモリセグメントというのは

物理アドレスを コード・データ・スタック などなどの領域にぶった切ってから

プロセスにそれぞれの領域を1つずつ渡していくのですか?

図がプロセスに割り当てられたメモリだけを示しているのか

それとも、

メモリ全体を示しているかでかなり解釈が変わってくると思うのですが・・・

--

もしくは・・・

プロセスがOSから渡された、連続に並んで見える仮想アドレスを

プロセスが勝手にメモリセグメントの領域を決めるんですか?

(うまく伝えずらいですが・・・)

分からないので教えてください。
言い方表現で誤っているところ・何を言っているのかわからかったら
修正依頼お願いします・・・。
イメージ説明
イメージ説明
イメージ説明
イメージ説明
0から作るOS開発 Vol.1 ブートローダー編 0から作るブートローダー

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2019/11/18 14:30

セグメントレジスタというのは、むかしの8086時代、16ビットCPUだった頃の話で、今では使われてません #だからこんな増築繰り返した歪な巨大なCPUはやめておけとw
kazuyakazuya

2019/11/18 23:21

そうなのしれませんが・・・ 参考書ではそれを中心に説明されているので できれば理解したいです・・・。
dodox86

2019/11/19 11:46

参考にされていると思われる書籍のページのキャプチャー画像を無造作に貼られていますが、良いのでしょうか。
kazuyakazuya

2019/11/19 11:52

やっぱ、よくないですよね? なので、質問を閉じるときに画像のみ消す予定です。
horiegom

2019/11/20 02:12 編集

ア 既に公表されている著作物であること  OK イ 「公正な慣行」に合致すること OK ウ 報道,批評,研究などの引用の目的上「正当な範囲内」であること OK エ 引用部分とそれ以外の部分の「主従関係」が明確であること OK オ カギ括弧などにより「引用部分」が明確になっていること OK カ 引用を行う「必然性」があること おそらくOK キ 「出所の明示」が必要(コピー以外はその慣行があるとき) キ「出所の明示」がなされていません。 これらを全て満たせば著作権法32条に則る正当な行為になります。
y_waiwai

2019/11/20 02:19

言葉の意味にこだわっても意味ないんだけどなあ。 かんたんな8ビットCPUからやろう、というのも、 そんな大層な言葉にはなんの意味もない、ということを知るということもあるんだけど。
gentaro

2019/11/20 04:09

「ルール違反承知の上で」って書けば許されるわけではないので、違反してる自覚があるならやめましょう。
kazuyakazuya

2019/11/20 08:50

>かんたんな8ビットCPU 予算的にもちょっと今はできないです・・・。
dodox86

2019/11/20 09:22

> 予算的にもちょっと今はできないです・・・。 過去のご質問でも実費のお金の話が何回か出てきているようですが、回答者さんらの回答にかける時間プラス質問者さん自身の理解に費やしている時間をお金に換算したものを比べると、大した金額ではなさそうです。特に、16ビットでのセグメントレジスタを使った8086プログラミングは「理解しづらい」ものとして過去に何度も取りざたされていますので。実際に関わったプログラマーをしてそう言わしめるのですから、本だけ読んでもなかなか理解できないのは仕方ありません。
y_waiwai

2019/11/20 09:30

いやいや、Arduinoでいいんです 日本製でも千ナンボ、中華製なら2百ナンボで買えますがな 資料も揃ってるし、アセンブラでいじりたおしましょうw
dodox86

2019/11/20 09:42 編集

ArduinoですとCPUがAVRになって、アーキテクチャから何から変わってきますので、また理解の壁を作るかもしれません。まぁ、質問は閉じたことですし、この辺にしときましょう。。
guest

回答5

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 のフラットなメモリ空間を一つのセグメントに割り当てる(=フラットメモリモデル)のが常態化します。ここに至ってセグメントの意味は(コードとデータの分離と保護、及びメモリの仮想化の二つ以外)なくなったといってよいのです。

投稿2019/11/19 05:14

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/11/19 07:29 編集

回答ありがとうございます。 C言語をコンパイルし実行するとき、”スタック”というものが 使われていると思います。 その”スタック”と”スタックセグメント”は同じ・・・だと 思っていたのですが違うのでしょうか? (これが勘違いの根端・・・)
tacsheaven

2019/11/19 08:29

スタックセグメントは、「スタックのある場所」を示すための専用のセグメントだったのです。要するにコードともデータ(静的なデータエリア)とも分離したんですね。実際のスタックは(8086 の場合)SS レジスタと SP レジスタの組み合わせで、実メモリアドレスを決定していました。 同様に CSレジスタとIPレジスタの組み合わせで実行しているコードの位置を、DSレジスタと各レジスタないし即値の組み合わせでデータアクセスの実メモリアドレスを決定していました。
kazuyakazuya

2019/11/19 08:34

ありがとうございます。 あ、なるほど。だからこそ”スタックセグメント”ではなく”スタック領域”と言い方を区別しているんですね。 スタック領域・・・スタックとして使われているメモリ領域を概念的ないい方をしているってことか
kazuyakazuya

2019/11/19 23:05

(以降、メモリセグメント CPU 8086の話) CPU 8086では前者の互換性のために 68KBを1つのセグメントとして やることで、最大表現である1MBを有効利用した・・・。 それは分かったのですが その1つ68KBのセグメントには「~セグメント」みたいな 名前がついているようですが どうやってプロセスにメモリが分けられるのでしょうか? 64KBのセグメントに分けて、その1つのセグメントを1つのプロセスに振り分けたほうが仕組みが簡単なんじゃないかとも思ったのですが・・・
kazuyakazuya

2019/11/19 23:21

セグメントレジスターの数だけセグメントを作ることができる・・・ 名前は違うけど、機能・使われ方は変わらない・・・んですか?
tacsheaven

2019/11/19 23:54

処理するデータ量が多くなければセグメントレジスタの値を固定しておいて、高々64KBの世界で賄ってもよい(C コンパイラで「メモリモデル」の指定、ありませんでしたか?)のですが、データ量が多くなれば64KBを超える領域を扱う必要が出てきます。その場合はセグメントレジスタ(この場合DSとES、のちにはFSとGSが追加)の値を変更することで領域をずらしてアクセスするのです。 プログラムも同様で、コードが64KBを超えた場合はジャンプするときにセグメントレジスタも合わせて変更する far jump といった形式を取ります。 セグメントレジスタはあくまでも「今アクセスする領域」を示しているだけなので、プログラムがどれだけの領域を使っていてもいいのです。適時セグメントレジスタの内容を切り替えれば。
kazuyakazuya

2019/11/20 00:35

最初は固定長64KBだったが あとあとになって逆に足りなくなってきたから アプリケーションが直接セグメントレジスターをいじって 可変長になれるようにしたみたいですが もともと初めから、「データセグメント」「スタックセグメント」 といったものは存在していたんですか?
tacsheaven

2019/11/20 00:48

違います。回答に書いたように、80286 で増えた「プロテクトモード」において、セグメントの定義が変わったんです。従来(リアルモード)のセグメントは実メモリアドレスのオフセット(20ビット中の上位16ビット)を示していたのに対し、プロテクトモードではより柔軟に、メモリブロックを表すようになっています(このときメモリアドレスも16MB(24ビット)になっています) リアルモードは直接アドレッシング、プロテクトモードはセグメントディスクリプタを介した間接アドレッシング、といえます。
kazuyakazuya

2019/11/20 01:51 編集

だからこそ、従来の定義で言うならば "メモリセグメント方式"は"セグメント方式"とも言える・・・と?
kazuyakazuya

2019/11/20 02:04

それで、データセグメントやスタックセグメントに 分割したら、それらの一部ずつを プロセスが使うってことですか?
dodox86

2019/11/20 02:56 編集

横からすみません。 この質問は収束するのでしょうか。湧き上がる好奇心を否定することはできないですけど、kazuyakazuyaさんの知識は、今はまだ多くのことが「点」で終わっているのです。多くの回答者さんが答えている様々なことが、結び付かないでいる。それは「シェルコード」というただでさえ特殊なプログラミングをしたいと言うところに、断片的な解決策を見出そうと質問をされていることに表れています。 > それで、データセグメントやスタックセグメントに分割したら、それらの一部ずつをプロセスが使うってことですか? 違います。それは今のマルチタスクOSで考える発想が混ざっているのだと思います。前提が違うのです。16ビットの8086CPUを使う初期のMS-DOSなどのOSは、一部の常駐プログラムを除いて、シングルタスクで動いています。自プログラム以外に同時に複数のプロセスが動いている、と言う発想、と言うか前提がありません。アプリケーションのデータ領域が64KBで足りない場合は、自らがセグメントレジスタを操作して、64KBを超える領域にアクセスする必要があります。OSの管理する領域にアクセスすることもできるし、バグがあれば簡単に破壊できます。データセグメントやスタックセグメントを最初にその実行プログラムに割り当てるのはOSのローダーですが、割り当てられたが最後、その値に責任を持つのは、そのプログラム自身です。CS,DS,SSなどのセグメントレジスタはアドレッシングの際にどれが使われるかと言う点でCPUと言うハードウェアに依存していますが、どこにアクセスしているかは特に16ビット、あるいは32ビット80x86のリアルモードでは、OSからロードされたプログラム(≒プログラマー)自身が用途を把握して、責任を持ちます。
tacsheaven

2019/11/20 03:00

ああ、何を勘違いしているのか分かりました。データセグメントやスタックセグメントを定義するのは、OS ではありません。各プロセスが、必要な容量と用途のセグメントを定義して使っているのです。複数のプロセスで同じセグメントを共有することは(基本的には)ありません。 ※プロセス間通信のためにデータセグメントを共有したり、DLL のように複数のプロセスでコードセグメントを共有することはありますが、特殊事例です あるプロセスの「1番目のデータセグメント」と、別のプロセスの「1番目のデータセグメント」は、全く別のものなのです。それを制御するのが OS で、タスクスイッチと同時にセグメントディスクリプタの内容をごっそり入れ替えることで処理しています。 ですから各プロセスは、割り当てたセグメントの中については、他を気にせず自由に使用して良いのです。
kazuyakazuya

2019/11/20 03:56 編集

ありがとうございます。 そういうことか・・・ プロセスが”メモリセグメント方式”においてセグメントを決めるんですね。 (ほかでも同じだろうけど) dodox86さんの言う通り マルチタスクと仮想記憶の概念が入り混じっていました。 でも、メモリセグメントであろうとなかろうと プロセスがスタック・コード領域をどこのアドレスから 使い始めるのを決めるという点は同じですよね? (まだ誤解がある気がするのですが セグメントレジスターが登場する以前でも スタック領域の長さ・開始地点は プロセスが勝手に決めれたんでしょうか?)
tacsheaven

2019/11/20 04:05

8086以前では、実メモリアドレスをそのまま使っていましたし、自分以外のプロセスのことを考慮する必要はないので、スタックの開始地点については「あるがまま」に使用しています。(下手に変えると BIOS や Disk Operating System の動作に支障を来す可能性もある)
kazuyakazuya

2019/11/20 04:32

ありがとうございます。 腑に落ちない点が1つあるのでお願いします。 ・64KB固定では本来使える分を使えずもったいないので セグメントレジスターによって アプリケーション(プロセス)自体がセグメント長と開始地点を 制御できるようになった(しなければいけなくなった) ようですが 1つのセグメントにつき64KBですよね? すべてのセグメントの合計が64KBではないと 8bitCPUとの互換性はとれないんじゃないかと思ったのですが それは問題ないのですか?
tacsheaven

2019/11/20 05:40

リアルモードの場合は各セグメントは64KB固定です(セグメントレジスタは実メモリアドレス上位16ビットを指定するだけで、その中のオフセットは従来通りのアドレスとして64KB利用できる)。 プロテクトモードではセグメントのサイズは可変ですが、そもそもプロテクトモードにした時点で8bit CPU との互換なんてものは考慮する必要がないので、杞憂に過ぎません。 リアルモードにおいて全てのセグメントレジスタの値を同一にすると、64KBの領域に全てを詰め込むことになり、8bit互換となります。この状態を C コンパイラなどでは「small」メモリモデルと呼んでいます。
kazuyakazuya

2019/11/20 08:48

ありがとうございます。
kazuyakazuya

2019/11/20 09:23

https://ja.wikipedia.org/wiki/Intel_8086 64KBで足りなくなってくると、アプリケーションプログラマーが セグメントレジスタを直々に操作して長さを調節した・・・と書かれています。 当初、互換性のためにメモリセグメントという64KBのセグメントを使う 方法を使っていたが 後々になって64KBではどうしても足りなくなったので、 セグメントの大きさを操作した・・・だと思うのですが そうすると、リアル・プロテクト以前に互換性はなくなりますよね?
tacsheaven

2019/11/21 23:57

セグメントレジスタを書き換えながら使えば、64KB を超えるメモリアクセスも可能です。8bit 互換の(64KBで完結している)メモリモデル以外を選択した時点で、アセンブリレベルの互換性はなくなりますが、それは機能強化している以上当たり前のことですね。
kazuyakazuya

2019/11/22 00:54

ありがとうございます。 ここで気になっているのですが ここのwikiで書かれている >64KB以上のメモリ空間にアクセスする手法が用いられるようになった は、セグメントレジスターとオフセットを組み合わせて20bitを使うように なった、メモリセグメントのことを指しているんでしょうか?
tacsheaven

2019/11/22 01:38

その通りです。アセンブリのレベルで、アドレッシング時にセグメントレジスタの内容を常に意識する必要が出てくるため、煩雑になったのです。
kazuyakazuya

2020/01/14 02:19

見返していて引っかかったのですが 80286の時点のセグメント方式:プロテクトモード は仮想記憶とは言えませんよね? アドレスの仮想化はしていますが・・・
kazuyakazuya

2020/01/14 02:22

メモリのスワップイン・スワップアウトはセグメント方式では できないと聞いたので・・・
tacsheaven

2020/01/14 02:34

いえ、できますよ? 回答にも書いてますが、セグメントディスクリプタの情報として、「実メモリにある」状態かどうかは分かる(Presentビット)ので、そのときにスワップイン・スワップアウトをやるだけのことです。 実際にはセグメントディスクリプタをセグメントレジスタにロードした時点でPresentビットが立っていないとセグメント不在例外が発生し、例外ハンドラ内でメモリのスワップインや割り当てが行われます。
kazuyakazuya

2020/01/14 02:50

一応確認したいのですが HDDに退避させることがスワップアウトですよね? ページングを無効にした80386では 物理アドレス空間に複数のタスクの空間を共存させているが HDDに退避させることができず 物理アドレス空間が足りなくなったらエラーになる。 ・・・と言われていたのですが 確認してみたところ確かにPがありました。 (ページングと組み合わせて使うことを前提にしているとかではなくて?)
kazuyakazuya

2020/01/14 04:02 編集

すみません。なんでもないです
tacsheaven

2020/01/14 04:01

確かに80286では物理アドレスになるんですが、プロテクトモードでは仮想記憶1GBまでが利用可能です。 というのも、マルチタスクの OS で考えた場合、あるタスクにとってのアドレスAと、別のタスクのアドレスAは(同じ物理アドレスですが)別のものである必要があります(共有しているメモリ領域でない限り)。 これを実現するためにPresentビットを使用したスワップイン/アウトが利用されています。 ページングはより柔軟かつ効率的なメモリ管理のために 80386 から導入されたものです。
kazuyakazuya

2020/01/14 05:15

そのスワップイン・スワップアウトの処理をセグメント方式と組み合わせて 実装するかどうかはOSによるんですよね? (スワップを使うか使わないかはOSの自由) だから、もし このスワップ処理がないセグメント方式のOSを作成したら タスク同士メモリが重ならないように セグメントを割り振るような設計になるってことですか?
guest

0

こんにちは。

その「メモリセグメント」は、MMU(メモリ管理ユニット=仮想メモリを実現するためのハードウェア)と言うにはあまりに稚拙過ぎるハードウェアです。
8086という30年以上前のCPUで16ビットのアドレス・レジスタで無理っと20ビットのメモリ空間をアクセスできるようにするために工夫された仕組みです。
因みにその図は「メモリ全体を示している」がほぼ正解です。

その「メモリセグメント」とMMUのセグメント方式やページング方式をごっちゃにすると理解できる筈がありません。30年以上前の技術である「メモリセグメント」を今は使うことはまずありませんので、特殊なケースを除き忘れて良いと思いますよ。

セグメント方式のMMUは正直複雑怪奇で理解するのは超苦労する上に実際に使われる場面はあまりないので、ページング方式のMMUを理解すると良いと思います。ページング方式は比較的単純なので理解しやすいです。(と言っても結構難易度高いですが。)

投稿2019/11/18 17:24

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/11/19 00:44 編集

回答ありがとうございます。 語彙の使いかたから違っていたような メモリセグメントは「スタックセグメント」「データセグメント」 などの総称という意味だと思って使っていましたが どういう意味合いで使っているんですか? 32bitCPUくらいまでは「セグメント方式」を使っていたようですが 同じ意味で使っていますか? あと、ここで使われている 「セグメンテーション」 と 「セグメント方式」 一体なにが違うんですか?
kazuyakazuya

2019/11/19 02:31

今回表されている図では・・・ 物理アドレスを直接セグメント(スタックとかの)に区切って 直接つかうようなことを書いていますが ”セグメント方式”は、物理アドレスを スタックセグメントとか関係なく 区切っていって、これを与えられたプロセスが スタックとかのセグメント領域を決めるのだと思いましたが・・・。
Chironian

2019/11/19 03:28

(まず、無駄な空行を開けるのはやめましょう。見にくいですよ。) > メモリセグメントは「スタックセグメント」「データセグメント」 > などの総称という意味 その通りです。 > 32bitCPUくらいまでは「セグメント方式」を使っていたようです > 同じ意味で使っていますか? 回答にも記載したように「メモリセグメント」と「セグメント方式」は別物です。 前者は30年前以上の技術でアドレス空間を広げる単純な工夫です。後者はMMUの方式の1つです。 前者はメモリ保護を提供しません。後者はメモリ空間をプロセスごとに分離し、プロセス間のメモリ保護を提供できます。 > 「セグメンテーション」 と 「セグメント方式」 http://www.matlab.nitech.ac.jp/~matsuo/OS/OS10.pdf を見る限り事実上「同じもの」ですね。
kazuyakazuya

2019/11/19 09:03

ありがとうございます。 ELFファイルの ・コード ・テキスト などと Cを実行するときに使われる”スタック領域” ”セグメント”が混じり合った結果今回の勘違いが発生しました。 いまだに理解できない点が1つあるので教えてください。 私の参考書を見る限り・・・ セグメンテーション(セグメント方式)というのはセグメントという単位に区切って メモリを管理する方法のこと。 そのセグメントの大きさはセグメントレジスタを使って調整することができる。 (たぶん、ここまでは問題ない。問題は次から) で、実はそのメモリを区切ったセグメントに名前がついている。 ・スタックセグメント ・コードセグメント ・データセグメント とか・・・ 「メモリセグメント」と「セグメント方式」は違うとはどういうことですか? セグメント方式はメモリをセグメント単位で区切ることで メモリセグメントは、区切ったセグメントの名前・・・ってこと?
Chironian

2019/11/19 09:35

> 実はそのメモリを区切ったセグメントに名前がついている。 ついてません。MMUで構築されたメモリ空間にスタックセグメントなどの名前がついているというのは、どこの情報ですか? > 「メモリセグメント」と「セグメント方式」は違うとはどういうことですか? 逆に何故その2つが同じと思っているのですか? その質問は『「月」と「すっぱん」は違うとはどういうことですか?』という問いに等しいですよ。 私は「すっぽん(≒メモリセグメント)」と「月(≒セグメント方式)」は別物と説明しました。 前者はメモリ保護機能を提供しない古い技術、後者はメモリ保護機能を提供する高度な技術と。 > セグメント方式はメモリをセグメント単位で区切ることで > メモリセグメントは、区切ったセグメントの名前・・・ってこと? 違います。セグメント方式とメモリセグメントが同時に有効化されるコンピュータは、事実上存在しません。 月に住んでいるすっぽんがいないのと事実上同じです。
kazuyakazuya

2019/11/19 10:21

追記しました。 1,2枚目を見るとセグメントという単位でメモリを分けるんだとわかります。 3枚目で、セグメントレジスターがあるとわかります。 これを使って設定すればセグメントサイズを設定できる。 それでこれらは役割があると・・・ 4枚目で、いろんな種類のセグメントがあって役割が決まっているんだぁ・・・ ・・・となりました。
Chironian

2019/11/19 10:40 編集

追記された資料は、恐らく8086が持つ「メモリセグメント」の話ですね。 30年以上前の技術です。仮想メモリとは事実上無関係です。 仮想メモリの「走り」と言えないこともないのですが、「ロボットのおもちゃ」と「Boston Dynamics社のロボット」くらいの差があります。 https://www.youtube.com/watch?v=_sBBaNYex3E
kazuyakazuya

2019/11/19 10:48 編集

>仮想メモリとは事実上無関係です。 だとすると、ここではセグメント方式(セグメンテーション)の話をしているわけではない・・・ ってことですよね? 「メモリセグメント」と「セグメンテーション」は違うみたいですが あたかも同じように書かれているのはなぜでしょうか?
kazuyakazuya

2019/11/19 10:51

(30年前の技術とはいえ理解しておきたいです・・・)
Chironian

2019/11/19 11:19

> 「メモリセグメント」と「セグメンテーション」は違うみたいですが > あたかも同じように書かれているのはなぜでしょうか? それは著者さんに聞かないと分からないです。 ただ、8086のセグメント・レジスタの解説としてはあまり適切な印象は受けません。 あれは単に16bitでは不足したメモリ空間を20bitへ増やすための手段です。本来セグメント・レジスタは4bitで足りるのですが、16bitあるので64KBytes境界付近を触る時に便利だった記憶があります。(大昔に触った時の記憶ですが。) しかし、セグメント分割することにメリットはありませんでした。 意味があるなら現在でもそのような方式が生き残っている筈です。現在はアドレス空間を下手に分割すると不便になるだけなので「分割のないフラットな空間にする」ことが一般的です。
kazuyakazuya

2019/11/19 11:56

わかりました。 2枚目までは”セグメンテーション方式”の解説。 3枚目のセグメントレジスターから”メモリセグメント方式”の説明(・・・たぶん) なので、セグメンテーション方式のやつは見なかったことにします。 "メモリセグメント方式"では、メモリ全体を複数の種類のセグメントに分割する・・・ ってことですよね?
Chironian

2019/11/19 13:15

その通りです。
guest

0

コメント付けようかと思ったけど、、

セグメンテーション==セグメント方式

同じようで違う。コンピュータ、、特にPCの世界だと、インテルの影響が強く、8086で採用されたセグメント(セグメントレジスタ)なのかと思います。

ただ、既に、指摘されているように、セグメントは、コンピュータ専用の言葉ではなく、インテルのセグメントとその他のセグメントの意味が混在していると思います。
googleで、"セグメント"で検索したら、セグメントとは(グロービス経営大学院)が引っ掛かりました。また、google翻訳では、"segment" --> 切片、弓形、環節 とかが訳であります。
どれが正しいと、言うより、これらが混在して使われていると思います。

多分、多くの誤解の元となっている インテルのセグメントについては、Wikipediaにある セグメント方式より、プロテクトモード の方が、より適切かと思います。 元々、インテルの8086のセグメントが特殊で、当時、ライバル(?)だった、MC68000に対し、セグメントの方が優秀だとの論陣を(昔過ぎるので、出典が確認できませんが) を張っています。当時から、無理がある主張でしたが、勝者はインテルでした。(ほかの要因が大きいと思うが)
そんなで、「無理が通れば、道理が引っ込む」結果になったと考えます。

さて、肝心のセグメントですが、引用されている絵では、それぞれのセグメントが独立していますが、インテルのセグメントレジスタによる方法では、オーバーラップします。それで問題を起こさないか、というとそれは、コードを書く人、コンパイラ等が責任を持つ事になります。
また、色々なセグメントがあるのは、インテルのセグメントの名残りと、英語のセグメントの意味から、メモリ空間を区分するための分類ですね。(セグメントに分けた方が管理が楽、、ここで、上記の経営大学院のセグメントが意味を持つ)

さて、こういう視点で見ると、セグメントに分けるという事は、インテルCPUでの定義を離れ、メモリをグループ分けして、管理する手法と考えるのアリとなります。 (多分、これが、インテルのセグメントと混在していると思う)

その一方、メモリ管理の方法として、ページングがありますが、仮想メモリとかと関係しますが、分けて考える事だと思います。(重なる部分は大きいですが)

投稿2019/11/19 13:39

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/11/19 20:17

回答ありがとうございます。 CPUのアーキテクチャによって”セグメント”というのが 何を指しているのかが変わるのが厄介です・・・。 (当初、そのことに気づけなかった)
guest

0

どうも英語(カタカナ)が出てくると、専門用語と思ってしまう人が多いですが、英語圏では英単語は単なる意味を持った普通の単語です。セグメントという用語も、メモリ以外の分野でも使われています。
「(全体と対比しての)部分」という意味です。

データセグメント・コードセグメント・スタックセグメント・テキストセグメント

などのメモリセグメント(?)

は、メモリの分類で、
データセグメント・・・・読み書き可能なデータ領域
テキストセグメント・・・読めるが書けないデータ領域
コードセグメント・・・・実行できるコード領域。当然読める。普通は書けない
スタックセグメント・・・読み書きできるので広義のデーセグメントだがスタックとしてのみ使う領域

セグメント方式・ページング方式という仮想メモリを実現するにあたって、どうやって物理メモリと仮想メモリをどうやって扱うか 

仮想記憶機構のページング方式は、使われ方と関係なく固定長のページ単位で、メモリとディスクの間を移動します。セグメント方式は、固定長でなくOSが各種目的でプロセスに割り振った塊単位でメモリとディスクの間を移動します。

ということで、とくに意味上の関連は無いです。
仮想記憶のセグメントの単位と、メモリ分類のセグメントが一致しているということもないです。(たまたま一致はあるでしょうが)

投稿2019/11/19 11:50

otn

総合スコア84538

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/11/19 12:01

回答ありがとうございます。 Cで意識していたスタックは”スタックセグメント”または”スタック領域”と言えるみたいですが ”メモリセグメント方式”で出てきた”スタックセグメント”と混合した結果、混乱を生みました。 (さらになぜか、ELFファイルとかで出てくる.text .dataとかも・・・) ひとつ、よろしいでしょうか? メモリの分野である「~セグメント」は”メモリセグメント方式”以外の場面では登場しませんよね? (メモリセグメント特有のもの・・・?)
otn

2019/11/19 12:12

データセグメント、コードセグメントなどの用語のことですか? 他の分野で見たことは無いですが、特別な意味でもないので、他の分野で使われていてもおかしくないと思います。特にデータセグメントはありそう。て、ググったらありました。 https://genesiscom.jp/utilize-segment-data/ 4つ固まってつかわれてるのはこのケースだけでしょうね。
kazuyakazuya

2019/11/19 12:17

ありがとうございます。(確かに用語といわれればそうかもれない・・・) 立て続き悪いのですが 仮想記憶で使われる”セグメンテーション方式”では”~セグメント”は一切ないですよね?
otn

2019/11/19 13:06

分けるというより、プロセスで必要な「~セグメント」の合計サイズだけ仮想メモリが割り当てられます。
kazuyakazuya

2019/11/19 23:13 編集

CPU 864において ページングでもセグメント方式(8086のメモリセグメントとは関係ないはず) でも、プロセスにメモリが割り当てられると 「スタック領域」や「データ領域」 (スタックとして使われるならスタック領域 初めからサイズが決まっているわけではない スタックとして使われているところをスタック領域と 言っているだけ・・・) という風に、メモリが使われると思います。 で、ここで出てくる「~領域」と 今回の8086CPUで出てくる 「~セグメント」は使われ方としては同じなのでしょうか?
otn

2019/11/20 02:26

> ここで出てくる「~領域」と今回の8086CPUで出てくる「~セグメント」は使われ方としては同じなのでしょうか? コードセグメントと、スタックセグメントの2つは両者(8086での意味と、メモリーの分類としての意味)で同じケースが多いと思いますが、同一概念と言うことでもないので、一致しない実装があるかも知れません(ちょっと思いつきませんが)。
otn

2019/11/20 12:08

画像をちゃんと見てませんでしたが、データセグメント・コードセグメント・スタックセグメント・テキストセグメントそれぞれの先頭を指す専用レジスタがあるように書いてありますが、これは特定のCPUの話ですね。一般論で言えば、各セグメントと特定のレジスタが1対1対応しているという限定は無いです。
kazuyakazuya

2019/11/20 13:25

少なくとも、8086では”メモリセグメント方式”で使う各セグメントを セグメントレジスターで設定・・・ アプリケーションプログラマーはセグメントレジスターを使って セグメントの大きさを変えることができたそうですが 本来、56KBにして8080とかとの 互換性を保ちつつ、1MBのメモリ領域を有効利用するために 1つのセグメントにつき固定長の56KBを与えていると思うのですが メモリ確保のためとはいえ、56KB長のセグメントにしなかったら 互換性はなくなり、メモリセグメント方式をわざわざ使っている 理由もなくなってしまうのではないかと 思ってしまうのですが・・・。
otn

2019/11/20 13:32

> メモリ確保のためとはいえ、56KB長のセグメントにしなかったら~~~~~ 以下の、ロジックがよくわかりません。 また、8086のセグメントの概念は、メモリセグメント方式とは直接関係ないです。 あと、56KBじゃなくて64KBです。
kazuyakazuya

2019/11/20 13:46

わかりました。調べなおします・・・。
guest

0

まず、セグメントレジスタのことは忘れましょう。

こういう大規模なCPUになると、CPUとは別に、メモリを管理するMMUというユニットがくっついてます
こいつは何をするかというと、メモリのアクセスを常に監視して、異常なアクセスを検知すると、CPUに対して例外割り込みを発生させ、動作を中断させる役割があります
#と書くと心当たりがあるんじゃないでしょうかw

とあるコードをメモリに展開、実行させるに当たり、OS(のカーネルは)MMUに対し、そのコードの実行ブロック、データブロック(その他コモンブロックやらスタックのブロックやら)にたいし、アクセス可否、書き込み可否、実行可否、のアクセス設定を課して、そのコードの実行におけるメモリアクセスを監視するように設定します。
さて、それに対し、どこかのアホがスタックエリアに実行コードを配置して実行させようとする、あるいはコードエリアを書き換えて別のコードを配置しようとすると、アクセスを監視してるMMUがその実行を強制的に止める、ということになってます

ということで、アクセス制限を課しているメモリブロック(セグメント)で、異常(フォールト)が起こると、例外が出て実行を止め、ウィンドウを表示させて告知しますね。セグメンテーションフォールトと。

投稿2019/11/19 00:50

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuyakazuya

2019/11/19 01:14

回答ありがとうございます。 例外はMMUによって引き起こされていたんですね・・・ あ、だからこそ メモリ保護がない(仮想アドレスを使っていない) FreeDOSなどなら 例外が起きないんじゃないか?という話だったんですね・・・ MMUによる「セグメント方式」では セグメントという可変長のブロックにメモリ全体を分けるそうですが このひとつひとつのセグメントが上から スタックセグメント・・・とかなっているんですか? (参考書の説明や、用語の乱雑でめっちゃわかりにくいですが・・・)
kazuyakazuya

2019/11/19 01:58

あ、いや 「セグメンテーション」自体が 仮想記憶がなかった時に使われていた メモリ分配(いいかたあれだけど) 方法のことみたいですね。
y_waiwai

2019/11/19 05:19 編集

まあ、Cなんかでも、メモリ配置するのにコードセグメント、データセグメント、という言い方をしてそのセグメントごとにアドレスを設定したりします まあ、用途ごとのブロックをセグメント、だと思っておけばいいかと。(ここらへんは単語の意味ですな)
y_waiwai

2019/11/19 08:00

他の方も書いてますが、「ブロック」とか「領域」のことだと思っときましょう セグメントという言葉にこだわってもしゃーないですぜ。
kazuyakazuya

2019/11/19 08:18

わかりました。 Cで使っているスタックに限っては・・・とりあえず領域 ”メモリセグメント”とは区別します・・・。
y_waiwai

2019/11/19 08:28

まあ、スタックにこだわってるようですが、、 PCのメモリってのは、別に区別はないです。 4Gのメモリを搭載すれば、4Gのエリアは別に区別のないフラットなすべて読み書き可能なメモリ空間です 回答に書いてあるとおり、OSはそこにコードにデータにスタックに、、と配置して、よーいどんで実行させる、というだけの話で、OSがそこはスタックだ!といえばそこはスタック領域(スタックセグメント)になるのです。
kazuyakazuya

2019/11/19 08:35

ありがとうございます。 スタック領域に対する疑問は晴れました・・・
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問