
前回は16ビットと32ビットを「文脈」によって切り替えるプリフィックスでした。これがあればx86(16bit)の命令がx86(32bit)に切り替わるっと。でもね、32ビットになって新設され、ピュアな32ビット操作だけというレジスタも存在します。その一つがCRx(xは0から7)で呼ばれるコントロール・レジスタっす。
※「ぐだぐだ低レベル プログラミング」投稿順indexはこちら
※実機動作確認には以下を使用させていただいております。
-
- Windows 11 PC (i5-1235U)
- Microsoft (R) Macro Assembler Version 14.33.31630.0
- WinDbg 1.2511.21001.0
「MOVD」もあるけどね、これはプリフィックス利用よ
x86(16bit)の過去回で練習した、整数型の汎用レジスタを対象に操作を行う命令ども、MOVだろうがADDだろうが全てが、前回のプリフィックスの影響下にあります。アセンブラがオペランドのビット幅とカレントのデフォルトを正しく認識できていれば、アセンブラが正しいコードを生成してくれるハズ。プログラマはあえて意識する必要はありませぬ。でもね、アセンブラに
MOVD
なんていう、ダブルワード(32ビット)専用のMOV命令とかあるじゃん、というご指摘ももっとも。しかし、この命令のエンコードをよくみたらば「オペランド・サイズ・プリフィックス」使われております。ことさらにDを明示しているだけで仕組みは変りませぬ。
プリフィックスの影響をうけない32ビット・レジスタもあり
さて80386以降登場した x86(32bit) 命令のほとんどは x86(16bit)命令の「読み替え」的解釈なのでありますが、新たに追加された最初から32ビットの命令というものも存在します。今回眺めてみるCR(コントロールレジスタ)に値を出し入れする命令というものもその一つです。レジスタの全貌が以下に。なお書き忘れましたが左MSB、右LSBっす。
命令エンコード的にCRは0から7まで8本使えるようになっているのですが、最初の32ビット機である80386では3本(+謎の1本)のみアサインされています。その後何時のころからかCR4が追加されてます。CRに関していえば、機種に応じていろいろレジスタやらビットやらが追加されておるので差異あり、ということです。
上記では、各CRのビットに色を付けてその拡張の「歴史」が朧気に分かるようにしてみました。
まずCR0ですが、この下16ビットは、16ビット世代の80286と連続性があります。80286ではMSWというレジスタ名で、専用命令、LMSW、SMSWでアクセスしてました。80386では、32ビットのCR0の下16ビットにMSWが押し込められてます。赤色のビットは80286時代と共通のビットです。最下位のPE(プロテクトモード・イネーブル)ビットを除けば、FPU関係のビットが並んでます。これにより80287とか80387「コープロセッサ」を制御できるというもの。
一方80386でCR0は32ビットに拡張されましたが、追加されたのは最上位(緑色)のPGビットだけです。ページング・イネーブルね。メモリ管理にページングを使うか否かのご指定(セグメンテーションは嫌でも最低限は使わざるを得ないのがx86のサガ。)他にも紫色に塗られたビットが複数存在しますが、それらは80386にはまだ存在せず、80486以降で追加されることになったもの。キャッシュとかいろいろあら~な。これはまた後でかな。
とりあえず「謎の」CR1は飛ばして、CR2とCR3ですが、これらはページングによるメモリ管理に必要なレジスタです。CR2はページフォルトが発生した場合にそのアドレスを保持するためのレジスタ。一方CR3はページ・ディレクトリ・テーブルの先頭番地を保持するためのレジスタです。x86(32bit)の場合、1ページは4Kバイト、ページ内アドレス12ビットで、ページ・テーブルも4Kバイト(1Kページ)毎の2段階構造です。そのため80386時点では上位20ビット(緑)のみが意味を持ち、下の12ビットは使われていなかったのが、後にキャッシュとか導入されるとページ・テーブルのキャッシング制御のために紫のところのビットなどが使われるようになります。
最後のCR4は、80386では存在しなかった制御レジスタで、命令セットを制御するのが主としたお役目みたいです。世代を経るにつれ、屋上屋を重ねるがごとくに「増築」を繰り返すx86なので、こういうレジスタでもないと収まりが付かなかったんでしょう。とりあえず今回は80386レベルで行きたいのでパス。
さて最後に「謎の」CR1です。これは80386時点でも、触ると例外になるレジスタとして「一応実装」されていたみたいです。そして「新たなコープロセッサ」向け拡張予約みたいな思わせぶりなことが書かれてます。しかし、ここに何か実装されるということはなかったです。知る限り。
8087に源流を持つ「浮動小数点コープロセッサ」ですが、80287、80387では単なる浮動小数点計算IO的構造になって「コープロセッサ」的な活動は影を潜めて?ました。しかし、これを良しとしない人々がいたのでしょう。なんといってもFPUは速度が命、今のままのFPUじゃ不満だと。80486ではFPUがオンチップ化されますが、これはx87系の延長で高性能化とは言い難いです。ただし、年寄は知っています。当時インテルのチップの「コードネーム」は単純明快、プロセッサならPチョメチョメ、FPUならNチョメチョメと(チョメチョメには数字)といったネーミングです。そして
N10
というチップがあったのです。「エヌテン」っす。スーパスカラーで浮動小数点計算を並列実行できる強力なマシンです。もともとコープロセッサという立ち位置でN10として始まったものの、整数演算も速いし、この際ホストのx86なんて不要ということになって「独り立ち」してしまったRISCマシンです。知らんけど。
順当に行けば、80486内蔵の廉価なFPUに対して、外付けの高価で高性能は数値演算プロセッサとなる筈が、独立したプロセッサになってしまったもの。その名は、
i860
です。いまどきの若者は知らんでしょうが、インテルも高性能RISCマシン(スーパスカラー)出していたのよ。そして、N10「エヌテン」のコード名は当時マイクロソフト社で開発が進められていた「新世代の」WindowsOS、WindowsNT(末尾のNTはニューテクノロジーではなく、N10のことだという噂あり)に対応していたと。
CR1、もしかするとコイツの制御レジスタの予定地だったところ、だったかと。老人の妄想か。多数あるx86の黒歴史の1ページか?