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

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

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

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

開発経緯 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月に出荷された。

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

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

レジスタの追加と拡張 汎用レジスタ (GPR) 数はIA-32の8本 (EAX,EBX,ECX,EDX,ESI,EDI,EBP,ESP) に更にR8〜R15の8本を追加して16本に増やされ、各レジスタのビット幅も32ビットから64ビットに拡張された。IA-32は汎用レジスタが少ないことからコンパイラによる最適化に限界があり、これが最も大きな欠点とされた。AMD64に最適化されたアプリケーションでは、レジスタ本数の増加によって性能向上が見込まれ、特に深いループを持った演算主体のソフトウェアでその傾向が強いと見込まれる。さらに128ビットのXMMレジスタの本数も8本から16本に増やされた(Streaming SIMD命令で使われる)。呼出規約においても、引数渡しがIA-32では原則としてスタックのみを使用していたのが一部の引数についてレジスタ渡しに変更されたり、呼出に際して一部のレジスタの上書きを容認するなど効率が上がっている。これらの新しい呼出規約は、当初からレジスタ本数が多いRISC系CPUではすでに実績があった仕様である。 アドレス空間の拡張 AMD64アーキテクチャでは、初期の仕様で48ビット(仮想アドレス空間サイズで256テラバイト)、追加機能で57ビット(仮想アドレス空間サイズで512ペタバイト)の仮想アドレス幅を持つ。IA-32アーキテクチャにおいて初期のプロセッサでは、仮想アドレス空間は32ビットで表現できる4GiBに制約され、Pentium Pro以降の実装で追加された物理アドレス拡張機能を使用することで64GiBの物理メモリを接続できるが、その場合も仮想アドレス幅は広がらず、仮想アドレス空間はやはり4GiBに制約された。32bit版Windowsシリーズにおいては、OSの仕様でアプリケーションが利用可能なメモリはおよそ3GiBに制約される詳細についてはWindows NT系の表を参照のこと。。これに対しAMD64のLongモードでは、IA-32の物理アドレス拡張をベースに、仮想アドレス空間をまず48ビットへ拡張し(現状物理アドレス空間は52ビット)、将来の拡張で4エクサバイトまでの仮想アドレス空間をサポートできるようになっている。 命令ポインタ相対のデータアクセス 命令は、命令ポインタ(RIPレジスタ)を基準にデータを参照できるようになった。これにより、共有ライブラリや実行時に読み込まれるコードでよく使用される位置独立コード(position-independent code、PIC))が、より効率的に動作するようになっている。 SSE命令 AMD64アーキテクチャは、当初からインテルのSSEとSSE2をコア命令として採用している。これらの命令セットは、単精度および倍精度のパックド/スカラー演算機能を提供する。SSE2は、8ビットから64ビットの精度までのデータ型に対応する整数のパックド演算機能も提供している。これらの命令は32ビットモードでも使用できる。64ビットプロセッサの普及により、これらの機能は家庭用コンピュータでも広く使われるようになり、32ビットアプリケーションの標準が向上した。例えば、32ビット版のWindows 8ではSSE2命令が必要とされている。SSE3以降のストリーミングSIMD拡張命令セットは、アーキテクチャの標準機能ではない。 SSE/SSE2を標準機能としたものの、従来のx87 FPU命令、MMX命令も残されている。 No-Executeビット NXビット(ページテーブルエントリのビット63)は仮想アドレス空間のどのページが実行可能か、実行不可かを指定することができる。NXビットがセットされたページにあるコードを実行しようとするとメモリアクセス違反となり、実行できない。これは、リードオンリーページへの書き込みを実行しようとしてもできないことと似ている。No-Execute機能は、ウイルスなどがバッファーオーバランなどを使用して、オペレーティングシステムを乗っ取ろうとすることを難しくする。 類似の機能は、セグメントの属性として80286以降のプロセッサーに存在している。しかし、近代的なオペレーティングシステムではセグメント機能は古いものと見なされ、セグメントのベースを0、リミットを4Gバイト(32ビットOSの場合)に設定することにより、実質的にセグメントを使用していない。 AMDはリニアアドレッシングモードでNo-Execute機能を実装した最初のx86ベンダーである。No-Execute機能は、PAEを有効にすれば、32ビットOSでも使用可能である。 古い機能の削除 x86アーキテクチャーにある多くのシステムプログラミング機能は近代的なオペレーティングシステムでは使用されておらず、それら古い機能は、AMD64のLongモードにはない。それらは、セグメントアドレッシング、タスクステートセグメントを使用したタスクスイッチ、仮想86モードなどである(ただし、FS, GSセグメントは、オペレーティングシステム構造体へのエクストラベースポインタとして残されている)。これらの古い機能は、Legacyモードでは依然として、完全に実装されているので、これまでの32ビット、16ビットオペレーティングシステムは、修正なしにx64プロセッサー上で動作する。

動作モード 動作モード 必要なOS 再コンパイルの必要性 アドレスサイズの既定値 オペランドサイズの既定値 レジスタの拡張 典型的な汎用レジスタの幅 Longモード 64ビット モード 新しい 64ビットOS 必要 64 32 有り 64 互換モード 不要 32 32 なし 32 16 16 16 Legacyモード プロテクト モード 従来の 16/32ビットOS 不要 32 32 なし 32 16 16 仮想8086 モード 16 16 16 リアル モード 従来の 16ビットOS

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

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

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

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

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

AMD64を採用するCPU 以下のマイクロアーキテクチャを採用したプロセッサは、AMD64を実装する K8(一部のモデルのみ) K10 Bulldozer/Piledriver/Steamroller/Excavator Bobcat/Jaguar/Puma Zen/Zen +/Zen 2 Zen 3/Zen 3+/Zen 4 Zen 5

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

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

当初プロジェクトは、Yamhillオレゴン州の ウィラメットバレー(Willamette Valley)を流れるYamhill川から来た名前である。という開発コードネームで始まった。このプロジェクトの存在を否定し続けて数年が経ち、2004年2月のIDFで、インテルはプロジェクトが進行中であることを発表した。インテルの当時の会長クレイグ・バレットは、これが重要な機密の一つであったことを認めた"Craig Barrett confirms 64 bit address extensions for Xeon. And Prescott", from The Inquirer"A Roundup of 64-Bit Computing", from internetnews.com。

インテルは、AMD64互換命令セットの名称を数回 変更した。IDFで用いられた名前はCT(Clackamas Technologyオレゴン州を流れるウィラメット川 (Willamette River) の支流、クラカマス川 (Clackamas River) の名称に由来する)、その数週間後にIA-32e(IA-32 extensions)と呼称を変更し、2004年4月にはこれを EM64T(Extended Memory 64 Technology)という名前で公式に発表した。製品リリース後の2006年7月27日には、インテルはEM64TをIntel 64と改称している"Intel® 64 Architecture"。

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 (XD) ビットと呼んでいる。この機能はすぐにNocona(Xeon系列)にも実装された。8xx/6xx/5x6/5x1/3x6/3x1シリーズのCPUは全てIntel 64が使用可能になった。また、Intel Core 2・Intel AtomでもIntel 64が採用された。

以下のマイクロアーキテクチャを採用したプロセッサは、Intel 64を実装する NetBurst(一部のモデルのみ) Core Bonnell(一部のモデルのみ) Nehalem/Westmere Sandy Bridge/Ivy Bridge Saltwell(一部のモデルのみ)/Silvermont Haswell/Broadwell Airmont Skylake/Kaby Lake/Coffee Lake/Cascade Lake/Comet Lake/Cooper Lake/Cannon Lake Goldmont/Goldmont Plus Rocket Lake/Ice Lake/Tiger Lake Tremont Alder Lake/Sapphire Rapids/Raptor Lake/Emerald Rapids/Meteor Lake/Granite Rapids/Sierra Forest Gracemont Arrow Lake/Lunar Lake

命令セット REXプリフィックス 次のような命令にはREXプリフィックスを使用する。 64ビットのオペランドサイズの指定 新しいR8〜R15レジスタ、追加されたXMMレジスタなどへのアクセス 64ビットレジスタであるRSP, RBP, RDI, RSIのビット0から7を、8ビットレジスタSPL, BPL, DIL, SILとしてアクセス。一方でREXプリフィックスを付けると8ビットレジスタとして AH, BH, CH, DHにアクセスできない。これにより直交性が高まった。 また、以下の命令は、デフォルトで64ビットのオペランドサイズであり、REXプリフィックスを必要としない。 ニア分岐命令 PUSH, POP命令 ENTER, LEAVE命令 暗黙のゼロ拡張 32ビットレジスタにデータを書き込むとその汎用レジスタの上位32ビット(ビット32から63)はゼロになる。 これは、コードサイズの最適化に使用できる。 一方、16ビットレジスタや8ビットレジスタにデータを書き込んでも、このゼロ拡張は起きない。

NOP(No Operation:オペコード 90h)命令は、かつてはXCHG EAX, EAXと等価であったがAMD64 Architecture Programmer's Manual64ビットモードではこの命令を特別に扱い、暗黙のゼロ拡張を適用せずRAXレジスタは変化しない。 CMOV(Conditional Move)命令では、64ビットモードでオペランドが32ビットの場合、条件が偽でもデスティネーションレジスタの上位32ビットはゼロになる。 即値 64ビットモードであっても、即値(Immediate value)は、32ビットのままであり、64ビットに符号拡張されて使用される。ただし、MOV命令のみ64ビットの即値が使用できる。 変位 64ビットモードであっても、変位(displacement)は、32ビットのままであり、64ビットに符号拡張されて使用される。ただし、RAXレジスタに対してのMOV命令のみ64ビットの変位が使用できる。 64ビットモードで廃止されたx86命令 以下のx86命令は64ビットモードでは廃止されたため、64ビットモードで実行すると不正命令例外が発生する。 AAA, AAD, AAM, AAS (ASCII Adjust Addition/Division/Multiply/Subtraction) BOUND (Check Array Bounds) CALL far absolute, JMP far absolute DAA, DAS (Decimal Adjust Addition/Subtraction) INTO (Interrupt to Overflow Vector) LDS, LES (Load Segment Register) POP DS, POP ES, POP SS, POPA PUSH CS, PUSH DS, PUSH, ES, PUSH SS, PUSHA オペコード 82h (Redundant encoding of opcode 80h: undocumented) SALC (Set AL According to CF: undocumented) LAHF, SAHF命令は、初期のAMD64, Intel 64では64ビットモードで廃止されたx86命令であった。 64ビットモードで再割り当てされたx86命令 ARPL (Adjust Requestor Privilege Level)命令は、64ビットモードでは、新しいMOVSXD命令になった。 1バイトのINC, DEC命令は、64ビットモードでは、REXプリフィックスになった。一方、2バイトのINC, DEC命令は、64ビットモードでも使用可能である。ただし、既存のINC, DEC命令をREXプリフィックスとして再割り当てしたため、32ビットのプログラムから64ビット命令は使用できない。 64ビットモードで廃止されたLDS, LES命令は、のちにインテルによってAVX命令のVEXプリフィックスとして割り当てられた。VEXプリフィックスに続く2バイト目を32ビットモードでは不正であった11xxxxxxという形式にすることにより、AVX命令は32ビットモードでも使用可能である。 64ビットモードで廃止されたBOUND命令は、のちにインテルによってAVX-512命令のEVEXプリフィックスとして割り当てられた。EVEXプリフィックスに続く2バイト目を32ビットモードでは不正であった11xxxxxxという形式にすることにより、AVX-512命令は32ビットモードでも使用可能である。

AMD64とIntel 64の差異 AMD64とIntel 64は、ほとんど同じであるが、僅かながら違いはある。これらの違いはオペレーティングシステム、コンパイラなどの開発者のみが意識しなければならない。アプリケーションプログラムの開発者がこれらの違いを意識する必要は、ほぼない。 差異 Intel 64では、SYSCALL, SYSRET命令は64ビットモードにしかない。SYSENTER, SYSEXIT命令は32ビット、64ビットの両方にある。 AMD64では、SYSCALL, SYSRET命令は32ビット、64ビットの両方にあるが、SYSENTER, SYSEXIT命令は32ビットモードにしかない。 Intel 64には、AMD64で定義されたSYSCFG, TOP_MEM, TOP_MEM2がMSR(model-specific registers)にない。 Intel 64では、64ビットモードでニア分岐命令に66h(オペランドサイズ プリフィックス)を付けた場合サポート外となる。AMD64では、仕様書通り16ビットオペランドとして実行される。 Intel 64では、LFS, LGS, LSS, CALL far indirect, JMP far indirect命令にREXプリフィックスをつけると、64ビットのオフセットをロードできる。AMD64ではこの機能は仕様書にない。 BSF, BSR命令はソースが0の場合、Intel 64では元々のx86と同様にデスティネーションは不定(undefined)であるが、AMD64はデスティネーションを変更しない。 Intel 64にはAMDのFast FXSAVE/FXRSTOR機能はない。 ハードウェア仮想化支援機能のIntel VT-xとAMD-Vは互換性がない。仮想化ソフトウェアはそれぞれに対応する必要がある。 Second Level Address Translation機能のIntel EPTとAMD RVIは互換性がない。仮想化ソフトウェアはそれぞれに対応する必要がある。

以前あった差異 AMD64には、元々はCMPXCHG16B命令はなかった。この命令は16バイト(128ビット)のメモリ領域を複数のCPUコアで排他的に共有することに使用される。この命令はWindowsで16TB以上の仮想メモリを使うために必要である。Socket AM2以降のAMD64で対応「BIOS and Kernel Developer’s Guide for AMD NPT Family 0Fh Processors」May 2006版 にRevision F(DDR2対応のSocket AM2版CPU)の変更点として「CPUID Fn[0000_0001]_ECX CMPXCHG16B (bit 13) added.」と記載されている。。 初期のAMD64, Intel 64は、64ビットモードでLAHF, SAHF命令をサポートしていない。この2つの命令はAHレジスタとフラグ間の転送命令で、元々は8ビットCPUである8080のプログラムを8086へ移植するのを容易にするために提供されていた8080のPUSH PSW命令をLAHF / XCHG AL, AH / PUSH AXとエミュレートできる。。64ビットモードでは、使い道があまりない命令のように見える。しかし、メモリにアクセスせず高速にフラグをコピーでき、VMwareなどの仮想化ソフトウェアがこの2つの命令に依存しているVMware Player 5.0 インストール要件。また、x87のステータスワードをフラグにコピーすることにも使用される。 初期のIntel 64には、PREFETCHW命令はなかった。この命令は、元々はAMDの3DNow!で導入されたキャッシュの最適化命令である。Pentium 4のCedarMillコアからIntel 64はこの命令を単にNOP(No Operation)として処理するようになったAMDのドキュメント「Cross-Vendor Migration」のPrefetch Instructionsにfamily 15/model 6/stepping 1以降のCPU、すなわちCedarMillコアからこの命令をNOPとして処理するようになったと説明がある。。NOPとして処理するIntel 64でもMicrosoft社のCoreinfoツールMicrosoft社のCoreinfoツールでこれらの命令のサポート状況を確認できる。は、PREFETCHWに対応と表示する。2013年のSilvermont、2014年のBroadwellよりPREFETCHW命令に正式に対応している。(上記3つは、Windows 8.1、Windows 10の64ビット版が初期のAMD64、Intel 64CPUにインストールできない制約事項となるMS公式サイトのWindows 8 のシステム要件ページにあるWindows 8.1節に「64 ビット PC に 64 ビット版 OS をインストールする場合、プロセッサが CMPXCHG16b、PrefetchW、LAHF/SAHF をサポートしている必要があります」と記載されている。 Windows 10 システム要件) 初期のIntel 64は、XDビット(AMD64におけるNXビット)をサポートしていない。したがってWindows 8(32ビット版、64ビット版とも)がインストールできない制約事項となる。

その他 POPFQ命令には、REXプリフィックスは必要ない。インテルのドキュメントにはこのことが正しく記載されていなかった。 同じオペコードに対するMOVDとMOVQの割り当てがIntel 64のドキュメントとAMD64のドキュメントで異なる。一方のドキュメント通りのアセンブリソースがアセンブルできない、逆アセンブル結果が想定と異なるといったことが起こり得る。

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

 コードセグメントディスクリプタのフォーマット 151413121110987654321 0ベースアドレス[31:24]GDLAVLリミット[19:16]PDPLS=1E=1CRAベースアドレス[23:16]ベースアドレス[15:0]リミット[15:0]

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

 データセグメントディスクリプタのフォーマット 151413121110987654321 0ベースアドレス[31:24]GD0AVLリミット[19:16]PDPLS=1E=0EDWAベースアドレス[23:16]ベースアドレス[15:0]リミット[15:0]

正規形(canonical form)