AMD64(x86-64)を徹底解説:歴史・仕組み・開発者が知るべき実務ポイント

はじめに — AMD64とは何か

AMD64(別名 x86-64、x64)は、従来の32ビットx86命令セットを拡張して64ビット長の汎用レジスタと64ビットアドレッシングを導入したアーキテクチャです。AMDが開発し2003年に商用化されたこの設計は、後にIntelを含む主要CPUベンダに採用され、今日のPC/サーバの標準的な命令セットとなっています。AMD64は互換性を重視し、既存の32ビットおよび16ビットアプリケーションを継承できる点が大きな特徴です。

歴史的背景

  • 従来のx86(IA-32)は16/32ビットの進化の上にあり、64ビット化には互換性と拡張性のトレードオフが存在しました。

  • AMDは互換性を優先する戦略で、IA-64(Itanium)が採られたEPICアプローチとは異なり、x86の流れを維持した64ビット拡張(x86-64)を提案・実装しました。最初の実装はAthlon 64(アーキテクチャ名K8)で、2003年に登場しました。

  • Intelも後に互換仕様(Intel 64 / EM64T)を導入し、現在ではx86-64が主流になっています。

アーキテクチャの主要ポイント

AMD64の設計上のポイントや実装上の特徴を整理します。

  • 64ビット汎用レジスタ:従来のEAX/EBX...に対応するRAX/RBX/...が導入され、レジスタセットが拡張されました。これによりレジスタ間での64ビット演算が直接可能になります。
  • 追加レジスタ:x86-64は汎用レジスタを8つから16個に増やしました(R8〜R15)。コンパイラ最適化やパフォーマンス向上に寄与します。
  • 長モード(Long Mode):64ビットの命令モードを指し、これにより64ビットの命令エンコーディングと拡張レジスタが有効になります。長モード内にさらに64ビットモードと互換モードが存在し、互換モードでは32/16ビットコードが実行可能です。
  • アドレッシングとカノニカルアドレス:仮想アドレスは実装により初期は48ビットまでサポートされ、上位ビットは48ビット目の符号拡張(カノニカル化)が要求されます。カノニカルでないアドレスは例外を発生させます。将来的には階層を増やして仮想アドレス空間を拡張する(5レベルページング等)拡張があります。
  • ページング:従来のページングを拡張し、4レベル(4KBページの標準)などの階層を使用します。大規模メモリ向けの大きなページや後発の拡張(大規模アドレスサポート)も存在します。
  • 命令セット互換性:x86の命令の多くをサポートしつつ、RIP相対アドレッシングなど64ビットで有用な機能を追加しました。

ABIと呼び出し規約(実務上重要)

ソフトウェア/OS開発においてはABI(アプリケーションバイナリインタフェース)が重要です。代表的なのはSystem V AMD64 ABIで、Linux系で採用されています。

  • 整数/ポインタ引数のレジスタ渡し:第一引数から順に RDI, RSI, RDX, RCX, R8, R9(整数)

  • 浮動小数点引数はXMM0〜XMM7で渡すことが一般的。

  • 戻り値はRAX(と必要に応じてRDX)に格納。スタックアラインメントは16バイトが必要。

  • ただしWindows x64では異なる呼び出し順(RCX, RDX, R8, R9)を使うため、クロスプラットフォーム開発では注意が必要です。

互換性とモード切替

AMD64は後方互換を重視しているため、OSとCPUが対応すれば32ビットと16ビットの実行環境を維持できます。長モード(64ビットモード)と互換モード(32/16ビットコード)を切替え、OSはプロセッサの制御ビットでモード遷移を管理します。

セキュリティと仮想化の拡張

  • NXビット:プロセッサのページテーブルに実行不可(NX)ビットを導入し、データ領域の実行を防止。AMDが先行導入したため「NXビット」として知られ、Intel側ではXD(eXecute Disable)と呼ばれます。
  • AMD-V(仮想化):ハードウェア仮想化機能を提供し、ネストされたページテーブル(RVI、またはNP)などの支援により仮想マシンのパフォーマンス向上を実現します。
  • メモリ暗号化/SEV:EPYC世代以降、暗号化機能(SEV: Secure Encrypted Virtualization)などを通じてVMのメモリを保護する技術が導入されています。

開発者向けの実務的注意点

  • 32ビット→64ビット移行時にはポインタの幅やデータ型のサイズ(longの扱いがOSで異なる)に注意する。Linux/Unix系ではlongが64ビット、Windowsではlongは32ビットのままである。
  • スタックアラインメント(16バイト)を守ること。コンパイラ最適化やインラインアセンブリで破るとSIMD命令でクラッシュする可能性がある。
  • アドレス空間が広がってもメモリ管理上の注意(キャッシュ、TLB、ページサイズ)が重要。大きなページ(2MB/1GB)を活用すると性能向上が見込める場合がある。
  • クロスプラットフォームでは呼び出し規約の差異(System V vs Windows x64)を意識すること。

将来展望とまとめ

AMD64は互換性と拡張性を両立させた設計で、パフォーマンスとエコシステムの面で成功しました。近年はアドレス空間のさらなる拡張、メモリ暗号化や仮想化支援、安全性を高める拡張などが注目されています。開発者はABI/呼び出し規約、データ型のサイズ、メモリ管理の観点で移行や最適化を行うことが鍵となります。

参考文献