0から作るソフトウェア開発

日々勉強中。。。

0から作るOS開発

環境準備

環境設定

ブートローダ

カーネルローダ

GRUB

カーネル

ドライバーその他

ブートローダその6 セグメント

前回までの内容

これまでで、 ということがわかりました。それでは前回の続きでCS、DS、ES、FS、GSレジスタとメモリアクセスについて

セグメントレジスタとメモリアクセス

セグメンテーションという言葉を聞いたことがありますでしょうか?

まさにそのセグメンテーションのセグメントを指定するレジスタがセグメントレジスタになります

セグメント?

セグメントとは、メモリをセグメントと呼ばれるある程度の大きさに区切ったものをいいます

ブートローダの説明で最初に出てきましたセクタは、ディスクを一定の大きさ(512バイト)に区切ったものでした

セクタと同じようにセグメントもメモリを区切ったものの単位だと考えてください

ただしセクタはそのディスクによって大きさが一定で記録される場所も(物理的に記録されているので)一定ですが

セグメントはサイズの上限がありますが、場所を変更したりすることができます

そしてセグメントどうしの領域がお互いかぶさるようにすることもできます

(同時にはセグメントレジスタの数だけしかセグメントはありません。そのかわり自由に変えることができます)

セグメントの位置は自由に決めることができる

セグメントの指定

このセグメントの開始位置を決めるのがセグメントレジスタCS、DS、SS、ES、FS、GSとなります

セグメントの位置を変えるには前回でてきましたMOV命令が使えます


MOV	DS, 0x07C0



上記のようにMOV命令にセグメントレジスタを指定して値を入れてやれば
セグメントの開始位置が変わります
ただし注意していただきたいのがここで入れたDSの値です

なにやら見たことのある値ですが、そうです、これでセグメントの開始位置が0x7C00になります

セグメントの開始位置はセグメントレジスタの値を変更することで変えることができる

セグメントの開始位置

セグメントの開始位置はセグメントレジスタで決めるのですが規則があります


セグメントの開始位置=セグメントレジスタに入れた値×16(16進数では0x10)



となります。上記での例でいうとDSに0x07C0を入れたのでDSで指定するセグメントは


DSのセグメントの開始位置=0x07C0×0x10(10進数では16)=0x7C00



と計算でき、DSが指定するセグメントの開始位置は0x7C00となります

これで位置を決めることができました。それでは大きさはどのようになっているのでしょうか?

セグメントの大きさ

CPUは16ビットで動作し、セグメントの開始位置を決めるセグメントレジスタも16ビットでした

同様にセグメントのサイズも16ビットの大きさになりますので0xFFFF(10進数では65535)+1になります

(アドレスは0x0000からはじまりますので+1をしています。時計も0時から始まり23時で合計24時間ですね)

ここまでのおさらいになりますが、16ビットモードでアクセスできる最大のセグメントのアドレスはどうなるのでしょうか

ここでDSに16ビットの最大値0xFFFFを入れた場合を考えてみましょう

その場合セグメントの開始位置は

DSの最大セグメントの開始位置=0xFFFF×0x10=0xFFFF0



となります。そしてセグメントの大きさは16ビット最大値の0xFFFFありますので、


アクセスできる最大アドレス=0xFFFF0(セグメントの開始位置)+0xFFFF(セグメントの大きさ)=0x10FFEF



となります。図でみると

DSに0xFFFFを入れるとアクセスできる最大のアドレスは0x10FFEF

となります。1MB(1024×1024=1048576バイト)を16進数で表すと0x100000となります

16ビットのリアルモードでは最大0x10FFEFまでのアドレスにアクセスできますので

(実際にはアドレスバスの都合上0x000FFFFまでのアクセスに制限されます)

だいたい1MBぐらいまでのメモリにアクセスできることになります



次回はセグメントにアクセスする方法についてです

inserted by FC2 system