2015年9月14日追記
思考実験的に書いてみた本コラムですが、2年たった現在では異なる考えを持っている箇所があります。修正を施そうかとも思ったのですが、あちこち修正するよりも当時のコラムは当時のままにしておき、そのことを文頭に表明しておく方がより良いのではないかと思えたので、本追記を加えました。
ご参照いただく際には上記のことを念頭においていただければと思います。
はじめに
Intelが初代8086を生み出してから、今日(こんにち)のIntel Core iシリーズ(Haswell)にも続く64ビット拡張までを順番に見てみたいと思います。その際に、64ビット拡張としてAMDが採った手法と、それまでのIntelが行ってきた拡張手法を比較し、Intelが最終製品に反映させなかったIA-32の独自64ビット拡張であるYamhill Technologyの姿について考察してみたいと思います(後述しますが、最終的にIntelはAMDの設計と互換性の高いClackamas Technologyを採用したため、Yamhill Technologyは市場に出ることなく終わりました)。
8ビットCPUとの懸け橋 – Intel 8086
Intel 8086(以下、8086)は現在まで続くx86系CPUの始祖にあたります。この8086は新設計の命令セットを採用していましたが、Intel 8080AやIntel 8085など、同社の過去の8ビットCPU用の資産を継承しやすい設計を採用しました。これにより、8086はその登場時点からソフトウェアがある程度そろっている状態を得ることができました。※1
具体的には、プログラムが扱う1次的なメモリ空間を16ビットとし、これをオフセットと呼びました。これに対してセグメントでメモリの実際の位置を補佐します。実際にアクセスするアドレス※2は「セグメントレジスターの値×16+オフセット」で決まります。
従来のプログラムは16ビットのアドレス空間を前提に記述されていたので、この方式は移植性を飛躍的に高める効果がありました。一方で新規に開発されるプログラムにとっては、16ビットのオフセットの範囲内でしか1次的にはアクセスすることができないという制限となる仕様でもありました。
セグメントレジスターは4つあり、2つは用途が固定されており(実行する命令用のコードセグメント「CS」と、スタックを管理する用のスタックセグメント「SS」)、残りはデータ用のデータセグメント「DS」と拡張用途のエクストラセグメント「ES」です。それぞれに別に値を設定し、異なるメモリ空間をアクセスするようにすることで、1つのアプリケーションはセグメントレジスターへの再設定をすることなく、最大256キロバイト※3のメモリを扱うことができます。
もちろんプログラムの動作中にセグメントレジスターの値を変更することで、任意の1メガバイトのメモリ空間へアクセスすることができます。
8086に存在するレジスターを以下に示します:
プロテクトモードの導入 – Intel 80286
Intel 80286(以下、80286)では、命令の高速化と8086の命令セットにいくつかの命令を追加するとともに、アドレス幅を20ビット(1メガバイト)から24ビット(16メガバイト)に拡張し、そのアドレス空間をOSが適切に管理できるようにするプロテクトモード※4を導入しました。これに対して、従来の8086との互換性が高いモードをリアルモード※5と呼びます。
命令セットはリアルモードとプロテクトモードの間で差がなく、ほぼ同じ命令※6が使用できます。※7 プロテクトモードでは、プログラムに特権レベルを設定し、レベル番号が低い方がより高い特権を持ち、低い特権レベルのプログラムから高い特権レベルのプログラムを破壊することができないように保護(プロテクト)するための仕組みが実装されました。また、これらの特権レベルの管理と所持するメモリの位置と範囲、そして使用目的などを管理するためにディスクリプターと呼ばれる構造体※8が導入されました。ディスクリプターは用途に応じて、セグメントディスクリプター、インタラプトディスクリプター※9などがあります。
プロテクトモードでは、セグメントレジスターに値を設定すると、そのセグメントレジスターの値(これをセグメントセレクターと呼ぶ)に対応するセグメントディスクリプターを読み出し、そのプログラムが使用可能なメモリであるか、設定先のセグメントレジスターが適切であるかなどを判定し、問題がなければ対象のセグメントレジスターとそのディスクリプターキャッシュレジスターの内容を更新します。これによって、そのセグメントレジスターを使用したアクセスで、新たなメモリ領域を指し示すことができるようになります。
リアルモードでは、セグメントレジスターへの設定値×16がそのままセグメントが指し示すメモリアドレスのベース値となり、そのメモリブロックのサイズとして64キロバイトを固定的に設定します。すべてのプログラムが最高特権で動くとみなされるため、この間に特権エラーが発生することはありません。
実は、プロテクトモードとリアルモードの差はこのセグメントの扱いだけです。リアルモードでプログラムが動いている最中もプロテクトモードと同じロジックで同じように動いているのです。これは表に見えるセグメントレジスターと実動のディスクリプターキャッシュレジスターが分離しているという仕組みのおかげで実現されています。
この80286のリアルモード、プロテクトモードなどを含むシンプルなアーキテクチャ※10は、CPU機能のユースケースとして以下のものを想定していたようです:
- セグメント値はOSが決定するもので、アプリケーションが決定するものではない。
- メモリの確保と、確保したメモリに対するセグメントディスクリプターの生成はOSが行い、そのセグメントディスクリプターに対するセグメント値をアプリケーションに返す。
- アプリケーションはOSが返したそのセグメント値をそのまま使う。
- アプリケーションが各種デバイスを直接制御しない。
- 特権チェックは常時行うが、リアルモードではディスクリプターキャッシュレジスターに常に最高特権が設定されているため、ごく一部のチェック(境界チェックなど)を除いて常に成功する。
確かにこれを前提とすると、Intelが当時主張していた「リアルモードとプロテクトモードでは同じプログラムが実行できる」ということをすんなりと理解できます。ただ、実際のアプリケーション、すなわちMS-DOS上で動作するプログラムは、セグメントレジスターの値を自前で設定したり、計算して値を出したりしていました。このため、先ほどの主張は「どこが?」「何を言っているの?」という評価をされていました。※11
リアルモードでは、ディスクリプターキャッシュレジスターに任意の値を通常の方法では設定できません。また、プロテクトモードに1度入ると通常の方法ではリアルモードに戻ることができません。※12しかし、通常ではない方法であれば話は別です。
その通常ではない方法とは、当時のIntelの公式ドキュメントには記載のなかったLOADALL
という非公開命令※13を用いるものです。この命令は80286に存在している各種レジスターに対してメモリ上から任意の内容を一斉に取り込むという機能を持っています。この命令を使えばプロテクトモードからリアルモードに戻ることも、リアルモードでディスクリプターキャッシュレジスターに任意の値をロードすることもできます。※14
80286におけるレジスターセットを以下に示します:
32ビットのシームレスな導入 – Intel 80386
Intel 80386(以下、80386)では、80286に対していくつかの命令追加※15と32ビットデータと32ビットアドレスの導入、セグメントではなくページ単位でのアドレス変換を行うページング機能の追加、セグメントレジスターの追加、制御用のレジスターやデバッグ用のレジスターの追加が行われました。※16
しかし、この変更は80386を組み込んだパソコンの価格を押し上げる効果を生むことが明白でした。従来のよりも多くのアドレス線、そして2倍の幅のデータ回路を作る必要があるためです。そんな中、なかなかIBMが80386の搭載機を出さなかったところに、PC互換機メーカーのコンパック(現在は吸収合併されてHewlett-Packardの一部となっている)が搭載機をリリースして、最初の一歩を踏み出しました。Intelも80386を搭載することでパソコンが高価となることを理解しており、その対策として80386のソフトウェアを実行可能でありながら、外部データバスを16ビット、アドレス幅を80286と同じ24ビットに制限したIntel 80386SX(以下、80386SX)を投入しました。※17そして、これと区別するために80386を「80386DX」と呼び変えました。
Intelは80386の開発において、80286を素直に32ビット化する方向で拡張を行いました。80286で導入されたリアルモードとプロテクトモードもそのまま継承して、その上で32ビット拡張を行いました。また、MS-DOSが広く普及している市場を意識して、プロテクトモードにおけるタスクのサブモードとして「仮想8086モード」が導入されました。
32ビット化によって、セグメントのサイズも最大4ギガバイトまで拡大し、セグメントベースでの仮想メモリの取り扱いが難しくなった※18ことから、ページングが導入されました。これにより、ページ単位でメモリの割り当てやスワップイン/アウトが行えるようになり、現代のOSがCPUに要求する要素のほぼすべてがそろいました。
命令は従来通りリアルモードとプロテクトモードでほぼ共通であり、リアルモードでも32ビット命令や追加されたレジスターを扱うことができました。プロテクトモードも従来の「将来のための予約」領域を使用して拡張したため、OSがこの32ビット拡張に対応さえしていれば、完全にシームレスに32ビット用のアプリケーションも旧来の16ビット用のアプリケーションも扱えるようになりました。
ディスクリプターキャッシュレジスターや、プロテクトモードとリアルモードの差をセグメントの扱いで切り分けるなどの80286で導入された手法がそのまま80386でも用いられています。仮想8086モードも、ディスクリプターキャッシュレジスターに設定される内容がリアルモードと異る、サブモードとして必要なものに変更されて扱われるようになっているものの、その仕組みはリアルモードの実装と大きくは異ならないものとなっています。
制御関連では、コントロールレジスターが導入され、プロテクトモードとリアルモードの切り替えやページング管理などを行うようになりました。従来は一度プロテクトモードに入るとリアルモードには特別な方法を用いなければ戻れないという制限がありましたが、コントロールレジスターの導入によってこの制限は解除されました。
この80386DX/SXで導入されたアーキテクチャがいわゆる「IA-32」の原点となりました。
80386におけるレジスターセットを以下に示します:※19
AMDによる64ビット拡張 – AMD64(コードネームx86-64)
IntelはHewlett-Packardと共同で新しい64ビットアーキテクチャ「IA-64」の開発行う一方で、IA-32の拡張はアドレスを順次小幅に拡張するだけにとどまらせるという選択を採っていました。このためOSから割り当てるメモリアドレス空間は4ギガバイトの壁を突破した※20ものの、アプリケーションが普通に使用できるアドレス空間は依然として4ギガバイトに制約されるという状況が続いていました。この消極的な対応は、IA-64によるCPUとIA-32によるCPUが競合するのを避けるための選択であったといわれています。
そんな中、Intel CPUのソフトウェア互換CPUを設計販売しているAdvanced Micro Devices(以下、AMD)が64ビット拡張の仕様である「x86-64」を発表しました。この仕様は、Intelがアドレス拡張を行うために設けた仕様に、さらに64ビット拡張を追加するものでした。
この64ビット拡張は、Longモードという新設のモードでのみ有効で、このモードに対応したOS環境下では、
- 汎用レジスターの数が2倍に増加(64ビットのタスクに限る)
- 汎用レジスターの64ビット化(64ビットのタスクに限る)
- セグメントの事実上の廃止によるフラットメモリモデルへの一本化(64ビットのタスクに限る)
- 一部の命令の廃止(64ビットのタスクに限る)
- 仮想8086モードの廃止
といった改廃が行われました。
AMDが公開している動作モードをまとめた表※21を以下に示します:
これは64ビット拡張モードを基軸とした動作モードの概念としては確かにわかりやすいのですが、実際の構造上の動作モードは以下の表の通り※22です:
まず、原理的にLongモードはプロテクトモードの拡張という形で実装されています。※23 しかし、64ビットのタスク(以下、64ビットモード)とそれ以外のタスク(以下、互換モード)は完全に別の扱いとなっています。
64ビットのレジスターや追加されたレジスターを使うことができるのは、64ビットモードで動作するプログラムに限られます。決して32ビットアプリケーションや16ビットアプリケーションが動作する互換モードのタスクからは使用できません。なぜこのような制限があるのかというと、64ビットモードと互換モードでは命令コードが一部異なるためです。この割り切りはIntelによるIA-32までの拡張では行われていなかった、非常に異質なものだといえます。
前述のように、Intelは8086系における拡張においてシームレスな拡張を行ってきました。80286でプロテクトモードを導入する際にも、80386で32ビット拡張を行う際にも、それぞれのモードで同じ命令コードを扱えるようにしてきました。しかし、AMDは64ビットモードの導入にあたり、このようなシームレスな拡張ではなく、従来のコードは互換モードだけで動けばよいと割りきり、64ビットのプログラムは64ビットモードで仕切りなおす、という命令コードの2分割化を行いました。
この仕様は後にAMDによる実装チップ販売の段階でコードネームの「x86-64」から「AMD64」へと改められ、さらにその後、Microsoftからの要請または圧力※24やその他もろもろの要因により、ほぼ互換の仕様をIntelが採用しました。
IntelによるIA-32の64ビット拡張 – もう一つのAMD64
このようにIntelは、最終的にAMDが設計したAMD64にほぼ互換の命令セットを「64-bit Extension Technology」として発表しました。その後あまり時を経ずして、今度はこの呼称を「Extended Memory 64 Technology(略称、EM64T)」に変え、さらに「Intel 64」に変更しました。ただし、これはマーケティング上の話であって、Intelは現在でもAMD64におけるLongモードを、発表前に用意していた呼称である「IA-32eモード」と呼んでいます。※25
このAMD64とほぼ互換の仕様は開発コードネーム「Clackamas Technology」であるといわれています。これとは別に、それより前の2002年1月24日に64ビット拡張の開発コードネームとして「Yamhill Technology」というものがあると報道されていました。
このYamhill TechnologyがAMD64ほぼ互換のClackamas Technologyに切り替わったのは2003年9月~10月ごろだといわれています。
IntelがClackamas Technologyを実装したPentium 4とXeonは、柔軟なNetBurstアーキテクチャとYamhill Technologyのために実装済みであった64ビット演算回路※26を応用する形で実装し、2004年6月29日にはEM64T対応のXeonを発表しました。方針転換をしてからわずか10か月※27で実装を終えて製品投入まで行ったことになります。この異常に早い対応がPrescottの柔軟性の高さを示しています。※28
これに対して一般向けのPentium 4にEM64Tがもたらされるのは翌2005年5月4日発表のPentium 4 5x1シリーズからです。※29
IntelオリジナルのIA-32に対する64ビット拡張
これらの状況証拠やその後にIntel64(≒AMD64)が実装されたCore 2シリーズの制限などから、Intelが計画してたオリジナルの64ビット拡張の仕様を推測してみます。ここでは、現在Intelが実装している64ビット拡張であるIntel64(=Clackamas Technology)とオリジナルプランの64ビット拡張であるYamhill Technologyを比較検討してみます。※30
Yamhill Technologyによる64ビット拡張は以下のような特徴を持っていたのではないかと推測します。
- オペランドサイズと汎用レジスターの64ビット拡張が行われる。
- 汎用レジスターの64ビット化に合わせてオフセットも64ビット拡張される。
- 汎用レジスターの数は増えない。
- 64ビット演算と64ビット汎用レジスターはどのモードでも使用できる。
- プロテクトモードが従来の仕様からシームレスに拡張され、64ビットがデフォルトになる各種ディスクリプターの拡張が行われる。
- プロテクトモードのシームレスな拡張であるため、仮想8086モードが廃止されることはない。
これによって現れるx64版のWindowsからの変化を考えると、表面上はWin16 APIを使用するアプリケーションが実行できるようになり、x86版と同様にDOSプロンプトを開くこともできるようになるでしょう。シームレスな拡張であれば、後方互換性は現状以上に確保されていたと想定できるからです。また、プログラムを書く人から見える点であれば、レジスター数が増やされないことから関数の呼び出し規約が現状のx64で行われているレジスター渡しからx86と同じ従来のスタック渡し(stdcall
すなわちPascal call)のままとなっていたのではないかと思われます。※31
推測の理由
これらの特徴を推測した理由を説明します。
汎用レジスターが増やされていないと推測した理由
IntelがNetBurstアーキテクチャの次にIntel64をサポートしたCore Microarchitecture(製品名Core 2シリーズなど)が、REXと呼ばれる新設のプリフィクス※32を苦手としていたからです。REXプリフィクスは増設されたレジスターや64ビットにかかわる制御などを行うプリフィクスです。Core MicroarchitectureではこのREXプリフィクスが付くとデコードに必要なクロック数が増加するという制限がありました。このことから、Core Microarchitectureの初期の設計時にはREXプリフィクスが存在していなかったことが示唆されています。
前述ハードウェアの実装例からだけではなく、REXプリフィクスの仕組みそのものから考えても、Intelによる64ビット拡張には存在しなかったのではないかと予想しています。なぜならば、REXプリフィクスはAMD64の64ビットモードで廃止した命令コード※33の割り当てを流用することで実現しているからです。このため、既存命令コードの廃止がなければ存在できないのがREXプリフィクスです。命令コードの割り当て上、新たなプリフィクスを設置するためには、既存の命令コードのどこかを空ける必要があります。シームレスに拡張を行ってきたIntelであれば、このような廃止を行わないであろうと推測しています。
すると、結果的に汎用レジスターを増やすことはなかったのではないか、という結論に至るわけです。
64ビット演算と64ビット汎用レジスターの一般化
Intel64ではIA-32eモード下の64ビットモードでしか64ビット拡張は使用できませんでした。しかし、80386による32ビット拡張のようにシームレスに64ビット拡張をするのがIntel風であるように思えることを考えると、おそらくはすべてのモードで64ビット拡張が使えたのではないかと推測します。
問題はオペランドおよびアドレスのサイズを16ビット、32ビット、64ビットの間で切り替えるその方法です。既存の命令フォーマットではディスクリプターキャッシュレジスターの内容に基づき、デフォルト16ビットあるいは32ビット※34となっており、デフォルトとは反対のサイズでアクセスする場合にはオペランドサイズオーバーライドプリフィクス※35あるいはアドレスサイズオーバーライドプリフィクス※36を付与して切り替えを行います。
素直に考えれば64ビット用の新たなプリフィクスを導入すべきですが、命令コードには空きがありません。
Intelがどのようなコード割り当てをしていたか、これについては明らかになっている情報からは正解がわかりません。一つのアイディアとしては、既存のアドレスサイズオーバーライドプリフィクスあるいはオペランドサイズオーバーライドプリフィクスを2つ連続で使用する、
- デフォルト64ビット → 1個のプリフィクスで16ビット → 2個のプリフィクスで32ビット
- デフォルト32ビット → 1個のプリフィクスで16ビット → 2個のプリフィクスで64ビット
- デフォルト16ビット → 1個のプリフィクスで32ビット → 2個のプリフィクスで64ビット
といったようなフォーマットが考えられます。※37
ただ、この方法ではデコーダーが従来以上に複雑化してプリフィクス出現に伴うペナルティの増加が発生すると思われるので、もっと違った方法が採られていたのではないかという気がします。
仮想8086モードが廃止されない理由
これは非常に単純な理由で「新設のモード」ではなく、既存のプロテクトモードのシームレスな拡張を行うだろう、という予想によります。仮想8086モードはプロテクトモードの配下にあるタスクに設定可能なサブモードです。ですから、プロテクトモードがそのまま拡張されるのであれば、そのまま仮想8086モードも残されるであろう、という推測するわけです。
まとめ
このように、AMDが行ったIA-32に対する64ビット拡張は従来のIntelが行ってきた拡張とはその方針が異なっています。そこで、もしもIntelがIA-32に対する64ビット拡張を行っていたら、という「もし」を推測してみました。実際の中身が「これだ」というところまで踏み込むことは当然できませんが「大体こんな風になっていたのではないか」という大枠はそんなに外していないのではないかと思います。
- 従来のプログラムとバイナリーレベル(実行用コード)での互換性はありませんが、ソースコードをアセンブルしなおすだけでほぼそのまま転用できます。
- このアドレスをEffective Address(実効アドレス)と呼びます。
- 1セグメントは16ビットのオフセットでアクセスするので64キロバイトの空間です。それが4つあるので、64キロバイト×4=256キロバイトということになります。
- 正式には「Protected Virtual Address Mode」です。これは「保護された仮想アドレスモード」という意味です。従来のIntel 8086と異なり、セグメントレジスターの内容がアドレスに直接計算される方法ではなくなったことで仮想アドレスモードと呼称したようです。
- 正式には「Real Address Mode」です。これは「Protected Virtual Address Mode」の反語となっています。現在の「Real Mode」と略された状態では「何がリアルモードなの?」という感じですが、要するにアドレスがそのまま決まるモードだということを意味していることが、ここからわかるかと思います。
- リアルモードでは特権の調整やタスクに関する命令は実行できません。
- リアルモードではすべてのプログラムが最高特権を持った状態で命令を実行できます。プロテクトモードでは、CPUの状態を変更するような命令は最高特権を持つプログラムでのみ使用可能で、その他の特権レベルのプログラムからは実行できません。
- 単数あるいは複数のデータの型を1つの型として定義したものを構造体と言います。
- 割り込み番号に対応するプログラムの情報が格納されたテーブルがあり、これを「Interrupt Descriptor Table(インタラプトディスクリプターテーブル)」略して「IDT」と呼びます。そのテーブルの1つ1つの要素をInterrupt Descriptor(インタラプトディスクリプター)と呼びます。
- 1980年代は外来語のアーキテクチャとは言わずに、設計思想と言われることが多かったです。
- しかし、実際のところIntelの主張通り、セグメントを自前で設定しない限り、リアルモードとプロテクトモードでは同じコードを走らせることができます。これを応用して、既存のMS-DOS用(リアルモード用)Cコンパイラーを使いながら、プロテクトモード上でプログラムを実行させるDOSエクステンダーも商品化されていました。
- 当時の用途ではプロテクトモードに入った後にリアルモードに戻れないと困ることが多かったため、プログラムから80286に対してリセット信号を送る機構が用意されていました。
- 後期にはMicrosoftがXMS(eXtended Memory Specification)を実装するにあたって利用していました。なお、80286の
LOADALL
命令はリアルモードに戻れない、という説もありますが、追試ができていません(当時、私は80386SXプロセッサーを搭載したPC-9801ES2を使用していたため)。もしも本当に戻ることができないのであればこのあたりの記述は変更する必要があるでしょう。時間があれば試したいところですが…。 - 当時のビットマップグラフィックの形式を扱いやすいようなビット操作関連命令が多数追加されました。
- 当時は現在(2013年8月)では考えられないほどメモリは高価で、2MBで4~5万円もしていました。このため、アドレスが32ビットで4ギガバイトのメモリ空間を持つことができるということは事実上の無制限であると受け止められていました。
- この80386SXは、細かい動作パターン、例えば特権の判定手順などが80386DXではなく、次のアーキテクチャである80486と同一に変更されています。
- ハードディスクにスワップする単位が大きくなりすぎて、このままでは32ビットでの仮想記憶の実装が困難となったわけです。
- ページング関連のキャッシュレジスターを除いています。
- Microsoft Windowsのクライアント版では4ギガバイト以上のメモリ空間をサポートしていませんが、Microsoft Windows 2000 Advanced ServerやDatacenter Server、Microsoft Windows Server 2003 Enterprise EditionやMicrosoft Windows Server 2003 Datacenter Editionなどではサポートされていました。
- AMD64 Technology, AMD64 Architecture Programmer’s Manual Volume 1: Application Programming : Publication No.24592, Revision 3.20, Date May 2013(PDF)の「1 Overview of the AMD64 Architecture」の2ページ目「Table 1-1. Operating Modes」を参考に日本語化したものです。ただし、筆者はこの表には誤りがあると考えています。正しくは以下のようになるべきです(変更点には着色強調しました):
16ビットOS、例えばかつてのWindows/286や80286用のOS/2があったことを無視すれば「必要なOS」項は「32ビットOS」であってもよいかもしれません。しかし、「典型的な汎用レジスターサイズ」が「32」なのは完全に誤りで「16」であるべきです(同じ表の「互換モード」での16対応アプリケーションを考慮した行で「16」としているのですから)。
- プロテクトモードに入ってから各種設定をしていくようになっています。
- 後藤弘茂氏がPC Watchで長年にわたって続けている連載「後藤弘茂のWeekly海外ニュース」の「ついにYamhillを公式に認めたIntel」に具体的な記載があります。関連個所を以下に抜粋引用します:
Yamhillが出てくるのは、Microsoftが、自社のWebサイトにアップしている裁判の証言記録( http://www.microsoft.com/presspass/legal/apr02/04-16ntranscriptam.asp )だ。この中で、AMDの元CEO Jerry Sanders(ジェリー・サンダース)氏が、MicrosoftのBill Gates(ビル・ゲイツ)会長兼CSAと、電話で交わした会話などについて証言している。
この記録はかなり長いが、これを読むとかなり前からYamhillについては、MicrosoftとAMDのトップの間で知られていたことがわかる。そして、MicrosoftとIntel、AMDの間で、64bitアーキテクチャを盾にした政治ゲームが繰り広げられていたこともわかる。
~ 中略 ~
この裁判の記録を見る限り、YamhillとAMD64に対するサポートで、Microsoftに対する綱引きが行なわれていたのは確かなようだ。また、Microsoftが両社の対抗を利用していたこともうかがえる。つまり、OSでのサポートを盾に、Microsoftは両社から何らかの条件を引き出そうとしていたように見える。
※下線強調は筆者による。
この引用の中で言われているMicrosoftが引き出したかった条件とはなんでしょうか?
Microsoftが求めているのは1本化されたIA-32の64ビット拡張であることに疑いありません。となると、引き出したかった条件は以下の通りではないかと推測します:
- AMDに対する条件
IntelがAMD64互換の実装をすることを許容することを見返りに、MicrosoftはWindowsをAMD64に対応させる。 - Intelに対する条件
IntelがWindowsを動作させることができる程度にAMD64互換の実装を行う見返りに、Microsoftは64ビット拡張対応のWindowsの発売をIntelの準備が整うと思われる半年程度延期させる。
実際、IntelはAMD64にほぼ互換のIntel 64を実装し、それに対してAMDは異議を唱えたり妨害したりはしませんでした。それと同時に、この記録の内容と前述の条件が成立するためにはIntelとAMDの64ビット拡張が非互換であるという前提が必要となります。このことから、当初から存在していたYamhill TechnologyはAMD64ほぼ互換路線であるClackamas Technologyとは別のものを指していたとの説を補強するものだといえます。 - AMDに対する条件
- 一般向けのマーケティングとは違って、技術者向けにはあれこれ無駄な変更はしないということなのかもしれません。
- 後藤弘茂のWeekly海外ニュース – Intelは昨年秋にAMD64互換を決めたに、
例えば、Prescottのダイ(半導体本体)写真を解析、Prescottの整数演算ユニットが2パイプになっていることを指摘したプロセッサアーキテクトのWebサイトもあった。デュアルの32bit整数演算パイプを組み合わせて使うことで、64bit演算を行なう仕組みになっているという解析だ。
という記載があるように、コードネームPrescottは当初から64ビットの演算パイプが存在しているといわれていました。
- 2003年9月に方針転換したと仮定した場合に10か月、同10月ならば9か月。
- このNetBurstアーキテクチャの柔軟性がなければ、いくらMicrosoftの要求であったとしてもIntelは飲むことはなかったのではないかと思えます。NetBurstアーキテクチャの柔軟性がAMDを結果として助けたのかもしれません。
- 最初の対応製品がPentium 4ではなくXeonであり、Pentium 4への導入が翌年にずれ込むあたりに、この時期のIntelにはIA-64に対する配慮が続いているように見えます。
- Intelによる2つの64ビット拡張を論じるため、AMD64ではなくほぼ互換のIntel64(=Clackamas Technology)とYamhill Technologyを比較する方が自然であるためです。
- IA-32はアーキテクチャレベルでOSとアプリケーション間の受け渡しをスタックを経由することを想定しています。例えば特権を超える際にスタックが切り替わりますが、この際にスタックに積まれたパラメーターを新たな特権のスタックに自動でコピーする機能が備わっています。
- 命令コードの前に置くことで、命令のオペランドサイズ、アドレスサイズ、あるいは対象などを変更する追加のコードをプリフィクスといいます。このほかに「プリフィックス」「プレフィックス」「プレフィクス」などと書く人もいます。英語のカタカナ表現は揺らぐのです…。
- 命令コードの
40h
~4fh
がREXプリフィクスのために廃止となりました。 - リアルモードではセグメントレジスターへの値のロードで常に16ビットが設定されます。
- Operand-size override prefix(オペランドサイズオーバーライドプリフィクス)は
66h
で、デフォルトのオペランドサイズを反転させる効果があります。 - Address-size override prefix(アドレスサイズオーバーライドプリフィクス)は
67h
で、デフォルトのアドレスサイズを反転させる効果があります。 - このプリフィクスによるサイズ切り替え順序は、既存の32ビットと16ビットのオーバーライドにおける互換性を加味しています。