レジスタを自分自身とXORすることは、それをゼロにするための慣用句です。なぜ減算ではないのでしょうか?
概要
x86アーキテクチャでレジスタをゼロクリアする代表的な方法について解説。
xor eax, eax命令がなぜ主流になったのか、その理由と歴史的経緯を整理。
sub eax, eaxとの比較や、CPU設計上の最適化事情も紹介。
IntelなどのCPUメーカーの対応や、他アーキテクチャ(Itanium)との違いも触れる。
実際のアセンブリコードの現場でのエピソードも交えて解説。
x86コンパイラがxor eax, eaxを好む理由
- xor eax, eaxは、x86でレジスタをゼロにする最もコンパクトな方法
- mov eax, 0よりも命令サイズが小さい(movは即値エンコードで4バイト必要)
- x86にはゼロレジスタが存在しないため、都度ゼロ化が必要
- xor命令のほかにもsub eax, eaxなどゼロ化できる命令は存在
- ただし、xorが主流になった理由は明確ではなく、慣習や偶然が影響した可能性
xor eax, eaxとsub eax, eaxの比較
- バイト数、実行サイクル数ともに同じ
- フラグレジスタ(EFLAGS)の影響
- xor eax, eax:AF(補助キャリーフラグ)は未定義
- sub eax, eax:AFはクリアされる
- その他のフラグ(OF, SF, ZF, PF, CF)はどちらもゼロ化に適切な状態
なぜxorが主流になったのか
- 初期のコンパイラがxorを選択したことで、そのまま慣習化
- 「コンパイラがそうしているから正しいはず」という集団心理
- Intelは両命令に**特別な最適化(命令デコーダでの検出・依存性解消)**を実装
- 入力に依存せず、ゼロレジスタへのリネームで実質「0サイクル」動作
- ただし他のCPUベンダーはxorのみ特別扱いのケースがあるため、xorの優位性が確定
余談・実際の現場エピソード
- sub r, rを使う開発者も存在し、アセンブリコードで個性が出る
- ItaniumアーキテクチャではxorトリックはNaTビットがリセットされないため無効
- Itaniumには専用ゼロレジスタが存在し、直接ゼロを代入可能
著者・背景情報
- 著者RaymondはWindows開発に30年以上携わるエンジニア
- The Old New ThingというWebサイト・書籍の作者
- Windows Dev Docs Twitterアカウントでも活動
- 技術的な話題から雑談まで幅広く発信