X64

x64またはx86-64 とは、x86アーキテクチャを64ビットに拡張した命令セットアーキテクチャ。

実際には、AMDが発表したAMD64命令セット、続けてインテルが採用したIntel 64命令セットなどを含む、各社のAMD64互換命令セットの総称である。x86命令セットと互換性を持っていることから、広義にはx86にx64を含む場合がある。

なお、インテルはIntel 64の他にIA-64の名前で64ビット命令セットアーキテクチャを開発・展開していたが、これは全くの別物であり、x64命令セット、x86命令セットのいずれとも互換性がない。

2023年4月にはIntelが、x64のLegacyモードを切り捨てることによりLongモードのみにしてサブセット化することで回路をシンプルにして性能向上するうえで問題になっているボトルネックを解消することを目標にしたX86-Sの提案の文書を公表した。もっとも、構想が発表されただけで、具体的な製品化に関する情報は発表されていない。

1. AMD64
--------

大元のAMD64は、AMDのOpteron、Athlon 64、Turion 64など最初に実装されたK8マイクロアーキテクチャとその後継製品に実装されている。

1.1. 開発経緯
---------

PC用アーキテクチャとして広く普及したx86は、半導体の製造技術とマイクロアーキテクチャの革新とともに性能の向上を続け、サーバやワークステーションといったエントリークラスのエンタープライズ市場でも広く受け入れられるに至った。しかし、IA-32の性能向上によって自社開発の64ビットアーキテクチャであるIA-64との競合を懸念したインテルは、x86の拡張を32ビットアーキテクチャの範囲に留めてIA-64との棲み分けを図った。これに対し、市場からは広く普及したIA-32アーキテクチャと互換性を保ちつつ64ビットに拡張した、よりコストパフォーマンスに優れたエンタープライズ製品の登場が待ち望まれていた。高収益を望めるエンタープライズ市場への進出を図っていたAMDはそうした需要に応えて、x86の64ビット拡張アーキテクチャとして、従来のIA-32のソフトウェアも利用が可能な命令セットとしてx86-64を発表した。その後の実際の製品発表でAMD64と改称された。この計画は、2000年8月に発表され、最初のプロセッサは2003年4月に出荷された。

1.2. 仕様
-------

64ビットの汎用レジスタを持ち、32ビットのx86より広いアドレス空間をサポートするため、大きいデータをより容易に扱うことができる。またx64は32ビットのプログラムコードと完全な後方互換性を持つ。全ての32ビットの命令セットが実装されているため、32ビットのx86実行ファイルは、互換性あるいは性能の損失なしに動作させられる。ただし、アプリケーションソフトウェアがx64の性能を活かすには、x64ネイティブコードを出力するコンパイラを用いることが必要である。

1.3. アーキテクチャの特徴
---------------

AMDがx86命令セットを64ビット化する際に使ったのは、x86命令の先頭にプリフィックスをつけるという手法である。プリフィックスを使うのは、インテルが16ビットCPU 80286を32ビット化するときに使った手法でもある。DEC Alpha の設計者の一人 ダーク・メイヤー が AMD64仕様の作成に関わり、彼をはじめとするDEC出身者の経験がこのプロジェクトに活かされた。特筆すべき点は以下のようなものである。

レジスタの追加と拡張 汎用レジスタ  数はIA-32の8本  に更にR8〜R15の8本を追加して16本に増やされ、各レジスタのビット幅も32ビットから64ビットに拡張された。IA-32は汎用レジスタが少ないことからコンパイラによる最適化に限界があり、これが最も大きな欠点とされた。AMD64に最適化されたアプリケーションでは、レジスタ本数の増加によって性能向上が見込まれ、特に深いループを持った演算主体のソフトウェアでその傾向が強いと見込まれる。さらに128ビットのXMMレジスタの本数も8本から16本に増やされた。 アドレス空間の拡張 AMD64アーキテクチャでは、現状の実装で48ビットのアドレス空間を持ち、256テラバイトまでのメモリを扱うことが出来る。IA-32アーキテクチャにおいて初期のプロセッサでは、アドレス空間は32ビットで表現できる4GiBに制約され、Pentium Pro以降の実装で追加された物理アドレス拡張機能を使用することで64GiBのメモリを接続できるが、1プロセスで利用可能なメモリ空間はやはり4GiBに制約された。32bit版Windowsシリーズにおいては、OSの仕様でアプリケーションが利用可能なメモリはおよそ3GiBに制約される。これに対しAMD64のLongモードでは、IA-32の物理アドレス拡張をベースに、論理アドレス空間を48ビットへ拡張し、将来の拡張で4エクサバイトまでの仮想空間をサポートできるようになっている。 関連：2進接頭辞 RIP相対データアクセス プログラムカウンタ  相対でデータにアクセスすることができ、リロケータブルな共有ライブラリのコードを作成できる。また、共有ライブラリを仮想アドレス空間のどこにでも配置することができる。 SSE 命令 AMD64アーキテクチャでは明確にインテルのSSEとSSE2を基本命令セットに組み込んでいる。SSE2はx87の80ビット浮動小数点数から 32ビット/64ビットの浮動小数点数に置き換えたものである。SSE/SSE2命令セットは追加の8本のXMMレジスタを扱えるように拡張された。SSEとSSE2がAMD64命令セットに組み込まれており、それが従来のx87 FPUや
MMXや3DNow!の機能をカバーする。x64版Windowsでの64ビットプログラムでは、FPU/MMXレジスタをコンテキストスイッチの際に保存しないようにすると噂されたが、実際には保存されるようになっている。 No-Executeビット NXビットは仮想アドレス空間のどのページが実行可能か、実行不可かを指定することができる。NXビットがセットされたページにあるコードを実行しようとするとメモリアクセス違反となり、実行できない。これは、リードオンリーページへの書き込みを実行しようとしてもできないことと似ている。No-Execute機能は、ウイルスなどがバッファーオーバランなどを使用して、オペレーティングシステムを乗っ取ろうとすることを難しくする。類似の機能は、セグメントの属性として80286以降のプロセッサーに存在している。しかし、近代的なオペレーティングシステムではセグメント機能は古いものと見なされ、セグメントのベースを0、リミットを4Gバイトに設定することにより、実質的にセグメントを使用していない。AMDはリニアアドレッシングモードでNo-Execute機能を実装した最初のx86ベンダーである。No-Execute機能は、PAEを有効にすれば、32ビットOSでも使用可能である。 古い機能の削除 x86アーキテクチャーにある多くのシステムプログラミング機能は近代的なオペレーティングシステムでは使用されておらず、それら古い機能は、AMD64のLongモードにはない。それらは、セグメントアドレッシング、タスクステートセグメントを使用したタスクスイッチ、仮想86モードなどである。これらの古い機能は、Legacyモードでは依然として、完全に実装されているので、これまでの32ビット、16ビットオペレーティングシステムは、修正なしにx64プロセッサー上で動作する。

1.4. 動作モード
----------

このアーキテクチャは、LongモードとLegacyモードという二つの動作モードを持つ。

1.4.1. Longモード
--------------

AMD64で拡張された部分に対応する動作モードである。これにはネイティブの64ビットモードと互換のための32ビットモードが含まれる。IA-32でのマイナーな動作モードはサポートされない。このモードは64ビットのOSで使用される。

基本的な命令セットは同じなので、x86コードを実行しても性能が低下することはない。インテルのIA-64では32ビットコードの性能低下が問題となったが、これは命令セットが全く違うためにエミュレート実行していたためである。

Longモードを使うと、64ビットOSは 32ビットアプリケーションと64ビットアプリケーションを並行して実行できる。また、AMD64は 16ビットのアプリケーションも実行することができる。しかし、Windowsの16ビットアプリケーション  のサポートに欠かせない仮想86モードは使用できないため、マイクロソフトは WOW64サブシステムでの16ビットアプリケーションの実行機能の実装を断念し、Windows XP Professional x64 Edition でのWin16アプリケーション実行をサポートしていない。これはWindows Vista以降のx64版にも引き継がれる制限となっている。

1.4.2. Legacyモード
----------------

このモードは、16ビットOSや32ビットOSで使用される。このモードにおいて、プロセッサは基本的にx86の32ビットプロセッサとして振る舞い、16ビットと32ビットのコードのみが実行可能である。Legacyモードは、仮想アドレス空間の4GB制限のような32ビットの仮想アドレッシング上の上限がある。64ビットのプログラムは、Legacyモードで起動することができない。

1.5. AMD64を採用するCPU
------------------

次のプロセッサは、AMD64を実装する:

AMD Athlon 64
AMD Athlon 64 X2
AMD Athlon 64 FX
AMD Athlon II
AMD Opteron
AMD Turion 64
AMD Turion 64 X2
AMD Sempron
AMD Phenom
AMD Phenom II
AMD Bulldozer  FX
AMD APU
AMD Ryzen
AMD EPYC

2. Intel 64
-----------

Intel 64は、IA-32アーキテクチャの64ビット拡張であり、インテルによるAMD64の実装である。

2.1. 開発経緯
---------

従来、AMDはインテルがオリジナルであるx86の互換プロセッサを開発・生産していた。しかし、x64では立場が逆転し、インテルはAMDが開発したAMD64アーキテクチャを採用した。

当初プロジェクトは、Yamhillという開発コードネームで始まった。このプロジェクトの存在を否定し続けて数年が経ち、2004年2月のIDFで、インテルはプロジェクトが進行中であることを発表した。インテルの当時の会長クレイグ・バレットは、これが重要な機密の一つであったことを認めた。

インテルは、AMD64互換命令セットの名称を数回 変更した。IDFで用いられた名前はCT、その数週間後にIA-32eと呼称を変更し、2004年4月にはこれを EM64Tという名前で公式に発表した。製品リリース後の2006年7月27日には、インテルはEM64TをIntel 64と改称している。

2.2. Intel 64を採用するCPU
---------------------

インテルで最初にIntel 64を実装したのは、//Nocona//というコード名で2004年6月に発表されたマルチソケットのXeonプロセッサである。Xeonはデスクトップ向け Pentium 4 をベースにしているため、同時期のPentium 4もIntel 64を実装しているはずだが、ハイパースレッディング・テクノロジーのときと同様、この機能は//Prescott//では最初は動かないようになっていた。これはおそらく初期の実装が完全ではなかったためで、インテルはその後Intel 64を使用可能にしたPrescottのE0バージョンをmodel Fとして販売し始めた。このバージョンではAMD64のNXビットに相当する機能がIntel 64でサポートされた。インテルではこれをeXecute Disableビットと呼んでいる。この機能はすぐにNoconaにも実装された。8xx/6xx/5x6/5x1/3x6/3x1シリーズのCPUは全てIntel 64が使用可能になった。また、Intel Core 2・Intel AtomでもIntel 64が採用された。

Intel 64を実装しているCPUは以下のものがある。

Xeon フィールド、Cビット、および、新しく定義されたLビットのみが有効である。L=1の場合、64ビットモードでプロセッサーが動作することを意味する。それ以外のベースアドレス、リミットなどは無視される。 　コードセグメントディスクリプタのフォーマット

 データセグメントディスクリプタ64ビットモードでは、データセグメントディスクリプタは、Pビットのみが有効である。それ以外のベースアドレス、リミットなどは無視される。ただし、FS,GSセグメントレジスタのみベースアドレスは有効で、MSRを使用して64ビットのベースアドレスを指定することもできる。のちにインテルは、特権レベル0以外でもFS,GSのベースアドレスを操作可能にするRDFSBASE, RDGSBASE, WRFSBASE, WRGSBASE命令を追加した。 　データセグメントディスクリプタのフォーマット

 正規形64ビットモードでは、仮想アドレスは64ビットであるものの、実際の実装では、264バイトのすべてを使用できるようにはなっていない。ほとんどのオペレーティングシステム、アプリケーションは、近い将来も含めて、そのような大きなアドレス空間を使用しない。フル64ビットという大きなアドレス空間のサポートは、複雑さとアドレス変換のコストを増やすだけでメリットはない。そのため、AMDは最初のAMD64の実装では、48ビットの仮想アドレス空間のみを使用することにした。さらに仮想アドレスのビット48から63は、ビット47の値がコピーされなければならないことにした。そうでない仮想アドレスを使用した場合は、プロセッサーは例外エラーを発生する。このルールに従ったアドレスは、正規形と呼ばれる。正規形のアドレスは、0から00007FFF'FFFFFFFFとFFFF8000'00000000からFFFFFFFF'FFFFFFFFの範囲であり、合計で256TBの仮想アドレス空間が使用可能である。この仕様は、実際に64ビット仮想アドレスが使用可能になったときに重要な意味を持つ。正規形ではないアドレスを使用した場合、例外エラーが発生するので、アプリケーションやOSが、未使用の上位16ビットを別の用途に使用できない。そのため、将来、仮想アドレス空間が48ビットから拡張されたときに問題が起こらない。 Longモードでのページ変換Longモードでのページ変換には物理アドレス拡張が必須である。Longモードに入る前にCR4のPAEビットを1にセットする必要がある。AMD64では、PDPE, PDE, PTEを拡張し、新たにPML4を追加した。PAEが有効になっているため、CR4のPSE(page-size
extensions)ビットは無視される。CPUIDのファンクション8000_0001hで、EDXのビット26がセットされていると、そのCPUは、1Gbyteページ変換に対応している。4Kbyteページ変換： PML4, PDPE, PDE, PTEによって変換される。ページのサイズは4Kbyteである。2Mbyteページ変換： PML4, PDPE, PDEによって変換される。ページのサイズは2Mbyteである。1Gbyteページ変換： PML4, PDPEによって変換される。ページのサイズは1Gbyteである。

3. 特権レベル
--------

特権レベルは80286のプロテクトモードでx86に導入され、レベル0,レベル1,レベル2,レベル3の4階層がある。リングプロテクションとも呼ばれる。x64の64ビットモードでも特権レベルは4階層あるが、通常は特権レベル0と特権レベル3の2種類しか使用されない。

コールゲートによるシステムコールコールゲートは80286で特権レベルを切り替える仕組みとして導入された。64ビットモードでは、コールゲートは64bitのオフセットが使用できるように拡張された。コールゲートの仕組みはRISCには無い。RISCにも対応していたWindows NTではシステムコールにコールゲートを使用せず、INT命令やPentium IIで追加されたSYSENTER, SYSEXIT命令を使用していた。 高速システムコール特権レベル3と特権レベル0を高速に切り換える命令として、AMDは64ビットモードではx86にあるSYSENTER, SYSEXIT命令は実装せず、AMD独自のSYSCALL, SYSRET命令のみを実装した。SYSCALL命令は、CS, SS, RIPをあらかじめセットされたMSRから特権レベルのチェック無しにロードする。このときRSPはロードされない。オペレーティングシステムは新しいSWAPGS命令を使用して、ユーザーモードのGSセグメントと、カーネルモードのGSセグメントを切り替え、GSセグメント経由でカーネルモードのRSPをロードする。なお、SYSCALLのオペコードは0Fh 05h、SYSRETのオペコードは0Fh 07hであり、これらはかつてx86に存在していた非公開命令LOADALLのオペコードを再割り当てしている。

4. オペレーティングシステムの互換性と扱い
----------------------

次のオペレーティングシステムは、x64アーキテクチャのLongモードをサポートする。

4.1. BSD
--------

4.1.1. FreeBSD
--------------

FreeBSDは、2003年6月の5.1-RELEASEで実験的なアーキテクチャーとして、amd64という名前でx64をサポートした。2004年1月の5.2-RELEASEでは公式なアーキテクチャーとして対応した。それ以来、FreeBSDでは、amd64をTier 1プラットフォームとしている。

4.1.2. NetBSD
-------------

x64アーキテクチャーのサポートは2001年6月19日にNetBSDのソースツリーに初めてコミットされた。2004年12月9日にリリースされたNetBSD 2.0では、NetBSD/amd64としてソースツリーに完全に統合され、公式なポートになった。32ビットのシステムコールのためのnetbsd-32カーネル互換レイヤーを通して、64ビットモードでの32ビットコードの実行がサポートされている。 NXビットは、実行不可のスタックとヒープを提供するために、使用されている。

4.1.3. OpenBSD
--------------

OpenBSDは2004年5月1日にリリースされたOpenBSD 3.5でAMD64をサポートした。ソースツリー内でのAMD64サポートの完全な実装は、実際のAMD64のハードウェアのリリースより前に行われていた。これはhackathonプロジェクトのためにAMDがいくつかのハードウェアを貸し出したためである。OpenBSDの開発者は、W^X  機能が容易に実装できるNXビットがあるため、AMD64プラットフォームを気に入った。 OpenBSDのAMD64ポートは、Intel 64でも走る。しかし、初期のIntel 64にはNXビットがないため、これらのIntelのCPUではW^X機能は使えない。後にIntelはXDビットの名前で、NXビットを追加している。

4.2. Linux
----------

LinuxはLongモードでx64アーキテクチャを動作させる初めてのオペレーティングシステム・カーネルとなった。これは、実際のAMD64のハードウェアのリリースより前の2001年、kernel 2.4にて始められた。Linuxは32ビット実行可能ファイルの実行に関して後方互換を保っている。これにより、32ビットプログラムの使用を継続しながらLongモード用にプログラムを再コンパイルすることが可能になった。

64ビット版Linuxでは、個々のプロセスで128TBの仮想アドレス空間と64TBの物理メモリが使用できる。

4.3. Mac OS X
-------------

Mac OS X v10.4のうちv10.4.7及びそれ以降のバージョンは、64ビットのインテルベースマシン上でPOSIX及び数学ライブラリを用いて64ビットコマンドラインツールが起動する。Mac OS X v10.4において、これ以外のライブラリ、フレームワークは、64ビットアプリケーションをサポートしない。このカーネル、およびカーネル拡張は32ビットのみである。

Mac OS X v10.5は、64ビットのPowerPCマシン同様に、64ビットのインテルベース・マシンにおいてCocoa, Quartz, OpenGL, そしてX11を用いた64ビットのGUIアプリケーションをサポートした。全ての非GUIライブラリとフレームワークは、このプラットフォームで64ビットアプリケーションをサポートしている。このカーネル、そして全てのカーネル拡張は、32ビットのみである。

Mac OS X v10.6は、64ビットカーネルをサポートしたMac OS Xの最初のバージョンである。しかし、最初のリリースでは、全ての64ビットコンピュータがサポートされたわけではなかった。64ビットカーネルは、32ビットカーネル同様に32ビットアプリケーションをサポートし、それぞれのカーネルも同様に64ビットアプリケーションをサポートした。32ビットアプリケーションは、いずれのカーネルにおいても仮想アドレス空間が4GBであるという制限があった。 64ビットカーネルは32ビットカーネル拡張をサポートせず、同様に32ビットカーネルは64ビットカーネル拡張をサポートしない。

OS X Mountain Lionは、64ビットカーネルのみサポートするが、32ビット、64ビットの両方のアプリケーションをサポートする。

Macは、x86/x64の32ビット・64ビットだけでなく、PowerPCとインテル・アーキテクチャのサポートなど、アーキテクチャの互換性問題が複雑に入り組んでいた為、ユーザが混乱しない為にOSレベルでユニバーサルバイナリなどの仕組みが整えられた。これは、一つのアプリケーションファイル、またはライブラリファイルに対して複数のコードをパッケージし、実行時に最適なバージョンが選択されるというものである。

4.4. Windows
------------

Microsoft Windowsは、2005年4月にWindows XP Professional x64 Edition、Windows Server 2003 x64 Editionをリリースし、x64に対応した。元来のx86版において、Windows XP の内部バージョンは 5.1.2600、Windows Server は 5.2.3790 であったが、x64 版においてはビルド番号が同一であり、システムアップデートも統一された。

Windows Vistaは2007年1月に、Windows 7は2009年7月に、Windows 8は2012年10月にリリースされた。いずれのOSも、x86 に加えて、64ビット 版としてx64をサポートするが、Itanium をサポートしない。

Windows Server 2008は2008年2月にリリースされ、x86 版、x64 版に加えて、IA-64もItanium版としてサポートした。Windows Server 2008 R2では x86 版のリリースが打ち切られ、x64 版と Itanium 版のみリリースした。Itanium 版はこの版が最終リリースとなり、Windows Server 2012 では x64 版だけがリリースされた。

x64版Windowsには以下のような機能がある。

1プロセスあたり8TB又は128TBのユーザーモード仮想アドレス空間。x64のプログラムは、"large address aware"オプションを付けてリンクされていれば、これらのすべてを使用できる。ただし、補助記憶装置の容量により使用できる最大値は、制限される。一方、32ビット版Windowsで提供されているユーザーモード仮想アドレス空間は2GBである。
オペレーティングシステム用の8TB又は128TBのカーネルモード仮想アドレス空間。一方、32ビット版Windowsで提供されているカーネルモードアドレス空間は2GBである。この増加した空間のメリットは、ファイルシステムのキャッシュやカーネルモードヒープに使用できる。Windows 8までのWindowsはプロセッサーで実装されている256TBのアドレス空間のうち合計16TBしか使用できない。これは、初期のAMD64がCMPXCHG16B命令をサポートしていないためである。
WOW64を使用して、既存の32ビットアプリケーションとダイナミックリンクライブラリを実行する機能。さらに、32ビットアプリケーションが"large address aware"オプションを付けてリンクされていれば、そのアプリケーションは64ビットWindows上で、4GBの仮想アドレス空間を使用できる。一方、32ビットWindowsでは、デフォルトの仮想アドレス空間は2GBで、/3GBのブートオプションを付けてWindowsを起動し、"large address aware"オプションを付けてリンクされたアプリケーションであれば3GBである。/3GBのブートオプションを付けて起動した32ビットのWindowsとは異なり、64ビットWindowsではカーネルモード仮想アドレス空間が減らない。そのため、32ビットアプリケーションは、x64用に再コンパイルしなくても、64ビットWindows上で動作させることにメリットがある。
32ビット、および、64ビットのアプリケーションは、"large address aware"オプションを付けてリンクされていなければ、仮想アドレス空間は2GBに制限される。
Windows XP/Vistaでは128GB, Windows 7では192GB、Windows 8では512GB、Windows Server 2003では1TB、Windows Server 2008では2TB、Windows Server 2012では4TBまでのRAMを使用可能。
LLP64データモデルを採用。intとlongは32ビット、long longは64ビット、ポインタとポインタから派生したデータ型は64ビットである。
カーネルモードデバイスドライバは64ビットでなければならない。32ビットのカーネルモードデバイスドライバは 64ビット版Windowsでは動作しない。ユーザーモードデバイスドライバは、32ビット、64ビットのどちらも64ビット版Windowsで動作する。
16ビットWindowsアプリケーションとDOSアプリケーションは64ビット版Windowsでは動作しない。これは、64ビットモードに仮想86モードがないため、64ビット版Windowsから仮想DOSマシンサブシステムを削除したためである。
NXページ保護機能の完全な実装。この機能は32ビット版WindowsでもPAEモードで起動すれば使用できる。
x86版のWindows NTファミリーでFSセグメントが使われている代わりに、x64ではGSセグメントがオペレーティングシステムが定義する2つの構造体を指している。ユーザーモードでのスレッドインフォメーションブロックとカーネルモードでのプロセスコントロールリージョンである。たとえば、ユーザーモードでは、GS:0はスレッドインフォメーションブロックの最初のメンバーのアドレスである。この規則を維持することによりx64版Windowsの開発が容易になった。しかし、AMDに対して、LongモードでFS, GSセグメントの機能を保持することを要求することになった。
Microsoft Visual Studio 2005以降では、64ビット版Windowsのみで動作する64ビットアプリケーション、32ビット版Windowsと64ビット版WindowsのWOW64上の両方で動作する32ビットアプリケーションの開発が可能である。

5. 脚注
-----

6. 参考文献
-------

[1]
[2]

7. 関連項目
-------

プロセッサ - 命令セット - レジスタ  - アドレッシングモード
32ビット - x86 - IA-32
64ビット - x64 / IA-64
Windows NT系#32ビットと64ビット

8. 外部リンク
--------

[3]
[4]
[5]