セグメンテーションの夢はどうなったのか?
(0)
- この記事は、「自作OS Advent Calendar 2016」の12/06が空欄だったので急きょ書くことにした記事です。
(1)
- 「30日でできる!OS自作入門」の読者の人たちは、みんなページングに憧れます。・・・まあそうですよね、ほぼすべてのメジャーなOSが使っている仕組みですし、たいていのCPUに搭載されている機能ですし、本の中では説明されていませんし。
- それに対して、セグメンテーションは不評です。できるだけ使わないほうがいいとまでいう人がいます。悲しいです。まあ読者の中にはいないかもしれませんが。
- 今日はなぜ私が「悲しい」と感じるのか説明してみたいと思います。
- OS自作入門では、112ページでセグメンテーションの説明があります。そこでは ORG 0 で書かれたプログラムたちが衝突しないために導入されます。つまりメモリの任意の場所を0番地にするためです。
(2)
- セグメンテーションが不評な理由を考えると、第一にそれは8086~80286のセグメンテーションが原因だと思われます。8086は1MBのメモリ空間を持っていましたが、アドレス指定に使えるレジスタは16ビットしかなく、つまり64KBしか使えないということでした。1MBを使い切るためには、そのたびにセグメントレジスタの値まで変更する必要があり、それはセグメンテーションが好きな私から見ても非常に使いにくい仕様でした。
- プログラムが100KBくらいのバッファを持つことはそう珍しいことではなく、64KBを超えたデータを扱うときはその都度セグメントレジスタを強く意識する必要があり、とても面倒だったのです。640x480x8ビットカラーをやろうと思ったらそれだけで300KBです。いかに64KBが小さいかわかるでしょう。
- 80286ではメモリが16MBまで増えましたが、セグメントの最大サイズは相変わらず64KBであり、もう救いがたい状況でした。・・・しかしこれはセグメンテーションが悪いというよりは、16ビットなのが悪いのです。16ビットだから64KBまでしか簡単にアクセスできないというのはまあ自然なことであって、それをセグメンテーションのせいにするのはちょっと話が違うようにも思います。
- ちなみに8086のライバルとされたMC68000は、16ビットのCPUといわれながらレジスタ幅は32ビットあって、64KBの制約などなく自由にメモリの好きな場所へアクセスできたのです。
- ではMC68000が16bitのCPUとしてはオーバースペックで、8086のほうが妥当なのかというと、私はそうは思いません。だって、Z80や6809は8ビットでしたが16ビットのレジスタを普通に持っていたからです。「16ビットCPUになったから32ビットのレジスタを持たなければならない」とまではいいませんが、8ビット時代を思えばMC68000みたいな仕様は不自然ではなかったのです。むしろ8086は不自然でした。
- まあ一説によると8086は8ビットCPUとの互換を意識しており、セグメンテーションでメモリを64KBごとに切り分けてそれぞれの中で8ビット時代の規模のプログラムが動くことを想定していたらしいので、そういう意味では8ビットCPUの感覚で作られたのかもしれません。それを80286まで引きずってしまったわけです。
- 80386が出て、整数レジスタが32ビット化されると、セグメンテーションは不便なものから便利なものに変わります。4GBまではセグメントレジスタを持ち替えずとも連続してアクセスできるようになったからです。
- セグメンテーションがあれば、0番地から始まる領域を同時に複数使わせることができます。たとえばプログラムコード用、データ用、スタック用、共有メモリ用、共有ライブラリ用、などです。特に共有ライブラリではとても便利で、なぜならどの番地のロードされるか悩まなくていいからです。0番地だとあらかじめ決め打ちできます。
- それぞれのセグメントに対して細かい権限の設定も可能です。
こめんと欄