『作りながら学ぶOSカーネル』 Chapter 03を読んでのつぶやき

いよいよプロテクトモード突入。

ソース3-1

  • ssは設定されているけれど、spが設定されてない。
  • プロテクトモード以降後のjmpでオペランドプレフィックスとアドレスプレフィックスの両方が必要なのだろうか?
  • プロテクトモード以降後、ssを設定しているが、やはりespは設定していない

p46

最大保存できる数字は64K(10進数で65535、16進数で0xFFFF)です。

64K=数値として格納可能な個数、65535=最大値の混用。

p54

非常に便利になった

セグメントアーキテクチャから見たとき便利になったと言えるかも知れないが、多くの場合、ベースアドレスを0にして4GBのメモリ空間を使用するフラットモデルが採用されることが多く、実質便利になっているかどうか。

p56

Gビットが(中略)1の場合にはLimit値に0xFFF(4KB:10進数で4096-1)を掛けた数字が限界点になります。

このリミット・フィールド(Limit値)の説明は完全な誤り。

  • Gビットが0のとき
    • リミット・フィールドはバイト単位で解釈される
  • Gビットが1のとき
    • リミット・フィールドは4Kバイト単位で解釈される
    • この場合、オフセットの下位12ビットはチェックされない(0x000から0xFFFはチェックされない)

というのが正解。
Gビットが1だと次のようになる。

  • リミット・フィールドが0のとき
    • セグメント・リミットは 0 × 4096 = 0 × 0x1000 = 0 と解釈される
    • これから有効なオフセットの最大値は 0 + 0xFFF = 0xFFF
  • リミット・フィールドが1のとき
    • セグメント・リミットは 1 × 4096 = 1 × 0x1000 = 0x1000
    • これから有効なオフセットの最大値は 0x1000 + 0xFFF = 0x1FFF
  • リミット・フィールドが0xFFFFFFのとき
    • セグメント・リミットは 0xFFFFF × 4096 = 0xFFFFF × 0x1000 = 0xFFFFF000
    • これから有効なオフセットの最大値は 0xFFFFF000 + 0xFFF = 0xFFFFFFFF

実際 0x1234 × 0xFFF ≠ 0x1234FFF、0xFFFFF × 0xFFF ≠ 0xFFFFFFFF です。

表3-2の出所は、体裁を見る限り、インテルのプログラミングマニュアルと思われ、そうだとすれば同マニュアルを参照されているはずなのに、この解釈(0xFFFを掛ける)になるのは何故だろう。

p60

このセグメントのLimitは(中略)0xFFFFFFFFになるのがわかります。

これはこれでよいけれど、ベースアドレスが 0x10000 に設定されているので、このLimitを加算すると4GBの範囲を越えてしまうのだが、良いのだろうか。物理メモリが4GB以上あれば試してみたいところだが、一般保護例外が発生すると予想。