資料集
ここはhideyosiの学習帳です。いろいろな資料を集めたり整理したりしています。オイラ用のノートなので間違っていたり未完成だったりしますので信用度は相当低いことをあらかじめご了承くださいませ。
1: 2005-07-21 (木) 15:48:05 ソース バックアップ No.1 を復元して編集 2: 2007-01-08 (月) 15:35:39 ソース バックアップ No.2 を復元して編集
Line 4: Line 4:
- +*16bit(8086)のセグメント [#qbded341]
- +
- +
セグメントとはなんじゃらほい? セグメントとはなんじゃらほい?
Line 26: Line 23:
「素」の理屈から言えばそうなる。これでは少なすぎるので、8086はちょっと変わった方式を採用している。 「素」の理屈から言えばそうなる。これでは少なすぎるので、8086はちょっと変わった方式を採用している。
-メモリアドレスを20ビットで表現できるようになっている。これなら、0x000000〜0xFFFFFF。つまり、16,777,215バイト。1MBとなる。+メモリアドレスを20ビット(16進数で5桁)で表現できるようになっている。これなら、0x00000〜0xFFFFF。つまり、1,048,575バイト。1MBとなる。
-しかし、レジスタは16ビット。これでどうやって20ビットを表現するのか?+しかし、レジスタは16ビット(16進数で4桁)。これでどうやって20ビットを表現するのか?
「セグメントアドレス」+「オフセット値」でアドレスを表現する。 「セグメントアドレス」+「オフセット値」でアドレスを表現する。
-セグメントアドレスもやはり16ビットでしか表現できない。で、それ+何番地ずれているかを表現する。+セグメントアドレスもやはり16ビットでしか表現できない。で、それ+何番地ずれているかを表現する。これが「セグメント」という概念。
たとえば、物理的に0x112233番地のメモリにアクセスしたいとする。その場合、レジスタはみな16ビットではあるが、 たとえば、物理的に0x112233番地のメモリにアクセスしたいとする。その場合、レジスタはみな16ビットではあるが、
Line 39: Line 36:
オフセットアドレス:0033 オフセットアドレス:0033
-これで表現する。 +これで表現する。図にするとこうなる。
- +
- +
- +
- +
 + 物理アドレス
 +  0x00000  ┌──────┐
 +          │セグメント  │
 +           │ (64kb) │  ┌─── ここを読みたい!
 +  0x10000  ├──────┤  │
 +          │セグメント  │  │        0x21000とかの指定はできない。
 +          │      │  │    (だってレジスタが16bitだもん)
 +  0x20000  ├──────┤  │
 +           │セグメント  │  │        そこで、セグメントレジスタにセグメント
 +           │      │←─┘    のベース番地を指定する。(頭4桁だけ)
 +  0x30000  ├──────┤
 +          │セグメント  │              0x2000:0x1000 (セグメントベース:アドレス)       
 +           │      │       これで0x21000にアクセスしてくれる
 +  0x40000  ├──────┤
 +     :     │セグメント  │
 +    :   :      :   
 +    :   :      :   
 +  0xE0000  ├──────┤
 +          │セグメント  │
 +           │      │
 +  0xF0000  ├──────┤
 +          │セグメント  │
 +           │      │
 +  0xFFFFF  └──────┘
 +   (1MB)
 +※少々乱暴な考え方をすれば、この16bit(8086時)のセグメントはとても変則的で無茶な方法といえるかも。整合性や理屈で考えれば、16bitのまま無理に1MBを使えるようにするより、20bitのCPUを開発するというのが本当といえないか。(もちろんあくまでも後付のお評論家的な話ってことで。)
 +*32bit(i386)のセグメント [#p6116747]
 +セグメントは元来は、上記の通り16bitでなんとか1MBのメモリを使うための変則的手法だったが、32bitになると使用法や意味合い・存在意義が変化する。
 +32bit状態になると、BXレジスタ(主にアドレスを指定する)も32bit化してEBXレジスタに変化する。32bitなのだから、0x00000000〜0xffffffffまで。すなわち4GBまで番地を直接指定できる。普通に考えればもうセグメントなど必要ではない。
 +しかし、32bit状態(i386)のCPUはマルチタスク(いくつものプログラムが平行して動作する)を意識している。そのため、この「セグメント」というメモリ分割管理の仕組みをうまく別の用途に転用することにしたようだ。
 +まず、GDTという、メモリ分割場所の表を用意する。この表はプログラム(主にOS)で設定する必要がある。GDT表はこんな感じになる。
 +|セグメント番号|セグメントの大きさ|セグメントの開始番地|セグメントの属性|h
 +|0|1MB|0x30000000|書き込み禁止|
 +|1|32MB|0xA0000000|OS専用|
 +|2|7MB|0x43880000|実行禁止|
 +|3|512KB|0xBA500000|OS専用,書き込み禁止|
 +|4|2MB|0x90000000|特になし|
 +|>|>|>|CENTER::|
 +|8,191|2MB|0xCF8600000|書き込み禁止|
 +※逆に言えば、GDTを設定しておかないとセグメントが使えない
 +~
 +~
 +この状態で、セグメントレジスタに「4」を入れ、EBXレジスタに0x00001111を入れてアクセスしたとする。するとCPUは、
 +--えーっと。セグメント番号は4かぁ。
 +--じゃ、GDTの4番を見に行こう。ええと、開始番地は0x90000000だね。
 +--大きさは2MBだから、EBXの値も問題ないね。
 +--属性も特に問題はないか。
 +--ええと、そうすると、0x90000000+0x00001111だから・・・
 +--そうか。物理的な0x90001111番地にアクセスすればいいのか!
 +と、こう判断して動作を実行する。
 +特にアプリケーションプログラムなどでは、作る段階では
 +-とにかくこのプログラムは、0x00000000番地に読み込まれてスタートするのだ!
 +という想定で作ればよい。OS側が適切にセグメントをセット&選択してくれるので、上記のような物理アドレスの位置をプログラムが意識しなくてもちゃんと動作してくれる。
-ここで登場するのが、「セグメント」という概念。 
-''模式図的概念'' 
-例えば、「電話番号」に置き換えて考えてみる。我々が住んでいる現世は沢山の家がある。しかし、電話番号にはある制約があって、一回に4桁までしか決められないとする。 
-そうすると、電話番号は9999までしか作れない。日本でたった千件しか電話をもてない。 
-これでは困る。そこで、「局番」というものを導入。局番には、「何処の県か?」という番号が振られている。だから、いままでは、2845という電話番号は、「日本全国の中の、2845番のお宅」という状態だったが、局番の導入によって、電話番号は、0012-2845という形になり、「北海道の2845番のお宅」「北九州のの2845番のお宅」という指定ができるようになり、電話番号をたくさん使えるようになった。 
-セグメントは、この「局番」に当たる。 


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   ページ新規作成 全ページ一覧 単語検索 最新ページの一覧   ヘルプ   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom
Counter: 5377, today: 1, yesterday: 5