"同じように動くことと、同じであることは、決して同義ではない。"
コンピュータシステムにおいて、
**「互換性(Compatibility)」**は絶対的価値として語られる。
- バイナリ互換
- ソース互換
- API互換
- ABI互換
中でも、バイナリ互換性は、
「既存の実行ファイルが、そのまま動く」という
魔法のような約束として尊ばれてきた。
だがアセンブリの視点でこの言葉を見つめ直せば、
その内実がいかに脆く、不確実で、幻想に近いものかが見えてくる。
バイナリ互換性とは何か?
バイナリ互換性(Binary Compatibility)とは:
「同じ実行バイナリ(.exe, .elfなど)が、異なる環境でも同じように動作すること」
を意味する。
例:
- Windows XP時代のアプリが、Windows 11でも動く
- x86でビルドされたアプリが、別のx86マシンでも動く
これは、ユーザー体験の継続性を支える重要な設計要件である。
なぜ互換性は幻想なのか?
バイナリ互換性は、「動く」ことだけに焦点が当たっている。
だがその裏では、綱渡りのような維持努力が続けられている。
1. OSレベルの偽装とレイヤー補正
- WindowsはAPIラッパーを通じて旧バージョンをエミュレートしている
- Linuxは
ld-linux
などのローダー互換性を調整し続けている
2. ハードウェアのエミュレーション
- x86は未だに8086の命令セットを保持している
- ARMではAArch32/AArch64のデュアル命令セットが併存
これらの努力はすべて、
**「過去を維持するための未来の犠牲」**によって成立している。
アセンブリ視点で見ると何が見えるか?
アセンブリから見た互換性の世界には、無数の分断と再構築の痕跡がある。
- 同じMOV命令でも、64bitと32bitでは内部動作が異なる
- セグメントレジスタは、あるアーキテクチャでは意味を失っている
- スタック配置やABIの違いで、同じ命令でも異なる結果を返す
つまり、
見かけ上は「動いている」ように見えるが、
その実体はまるで別物なのだ。
バイナリ互換性がもたらす設計上の歪み
バイナリ互換性を保つことには、代償が伴う。
- 冗長な命令セットの維持
- レガシーAPIのサポート負債
- セキュリティホールの温存(例:Win32の古典的脆弱性)
- 最適化阻害(古い形式との整合性を保つため)
設計者が新しい技術を導入しようとするたび、
過去との互換性が足枷になる。
それは、
「新しい設計を殺すのは、常に古い設計だ」
というジレンマの体現である。
完全な互換性など存在しない
たとえば:
- バイナリが動いていても、浮動小数点の丸め規則が変われば結果は変わる
- キャッシュラインサイズの違いで、性能が激変する
- パイプライン設計の違いで、タイミングが崩壊する(リアルタイム性が死ぬ)
このように、
バイナリが“動く”という事実は、何一つ保証しない。
そこにあるのは、限りない偶然と設計の残滓である。
「移植性」と「互換性」の混同
「互換性」という言葉は、しばしば「移植性」と混同される。
- 移植性:ソースコードや設計が、異なる環境でも容易に再利用できる
- 互換性:同一バイナリがそのまま動作する
両者は似て非なる概念だ。
アセンブリにおいては:
- 移植性は皆無(命令セットに強く依存)
- 互換性はハードウェアとOSの執念によって成り立っている
この違いを誤解すると、
設計が思考停止の泥沼に沈む。
真に設計者が目指すべきもの
設計者が重視すべきは、
**「透明性」と「制御性」**である。
- 今の環境で、なぜこれが動いているのか
- どの層に依存しているのか
- 将来、何を犠牲にしてでも維持されるのか
これを理解した上で、
**「偶然の上に設計を立てない」**こと。
バイナリ互換性は、
**今は使えるが、永遠に使えるとは限らない「幻の橋」**に過ぎない。
結語:幻想を設計に組み込んではならない
バイナリ互換性は、便利だ。
だがそれは設計者のためにあるのではない。
それは**「市場のための互換性」であり、「設計のための正しさ」ではない。**
設計者は幻想に惑わされてはならない。
本質的な設計とは、
- 構造の可視化
- 層の分離
- 依存の意図的設計
によってこそ成立する。
"互換性を信じるな。それが続く限りにおいて、感謝せよ。そして、それが壊れた時に、すぐ立て直せる構造を設計せよ。"