2026年2月21日土曜日

互換性の呪い コンピュータ史の負の遺産

現代のコンピューティング環境の深層には、数十年前に下された技術的決定が「技術負債」として埋め込まれている。既存資産との互換性を優先したために、非効率な構造を維持せざるを得なかった5つの代表的事例を解説する。



1. x86メモリセグメンテーション(8080の呪縛)

1970年代後半、Intel 8086は8ビットCPU(8080)からのスムーズな移行を目的として設計された。この時採用された「セグメント方式」が、後のPCのメモリ管理を極めて複雑にした。

  • 背景: 8080の16ビットポインタ(64 KB空間)を維持しつつ、1 MB(20ビット)の物理メモリを扱う必要があった。

  • 仕組み: 16ビットのセグメントレジスタを4ビット左シフトし、そこに16ビットのオフセットを加算する。

    • 計算式: 物理アドレス = (セグメント * 16) + オフセット

  • 代償: 16バイト単位(パラグラフ)での整列は当時のメモリ節約には有効であったが、後の32/64ビット時代においてもリアルモードの互換性として残り、現代のCPUの起動プロセスを複雑にしている。

項目内容技術的背景
レジスタ幅16ビット

8080とのソース互換性維持

アドレスバス20ビット

最大1 MBのメモリ空間をサポート

整列単位16バイト

高価なRAMを効率的に使うための細かい配置


2. Shift-JISとWindows Unicode移行の摩擦

MS-DOS時代に日本で定着したShift-JISは、Windowsが世界標準のUnicode(UTF)へ完全移行する際の大きな足かせとなった。

  • 構造的欠陥: Shift-JISの2バイト目には、ファイルパスの区切り文字であるバックスラッシュ(\ 0x5C)と同じコードが含まれる文字があり、誤動作の原因(0x5C問題)となった。

  • Windowsのジレンマ: Windows NTは早期にUnicode(当時は固定長2バイトのUCS-2)を採用したが、その後に普及した可変長エンコードのUTF-8との間で、内部処理(UTF-16)と外部規格の乖離が生じた。

  • 現代への影響: 下位互換性のため、Windowsは今も「ANSI API(ロケール依存)」と「Wide API(Unicode)」を併装しており、開発者に複雑な文字変換を強いている。

エンコード構造メリット現代の課題
Shift-JIS1/2バイト可変

旧来の資産と互換

0x5C問題、他言語共存不可

UTF-162/4バイト可変

Windows APIの標準

ASCIIとの非互換

UTF-81-4バイト可変

Webの事実上の標準

Windowsでは後付け対応


3. Gate A20(キーボードコントローラによるメモリ制御)

ハードウェアのバグ修正を、全く関係のない周辺機器の制御チップに押し付けた「場当たり的対策」の典型例である。

  • 発端: 8086にはアドレスの「巻き戻り(ラップアラウンド)」という挙動があった。これを前提とした古いソフトが、286以降のPC(PC AT)で動かなくなる問題が発生した。

  • 奇策: IBMは、キーボードコントローラ(8042チップ)の未使用ピンを使い、物理的にアドレスラインの21本目(A20)をオン・オフするスイッチを作った。

  • 結果: 高速なCPUが、メモリを広大に使うためにわざわざ低速なキーボードコントローラの反応を待つという、異様な処理が必要になった。


4. 予約されたファイル名(CON, NUL, AUX...)

Windowsで「CON」という名前のフォルダを作れないのは、1970年代のOSである「CP/M」の設計思想が今も生きているためである。

  • 概念: 通信ポートやプリンタなどのデバイスを「ファイル」として扱うための予約名(CON=コンソール、PRN=プリンタ等)である。

  • 互換性の壁: Windows NTカーネル自体にはこの制限はないが、Win32サブシステムが「古いソフトが壊れないように」と、わざわざチェックして作成をブロックしている。

  • 弊害: con.js などのファイルを含むプロジェクトをLinuxからWindowsにクローンすると、エラーが発生してリポジトリが壊れるといった現代的なトラブルを引き起こしている。

予約名元の意味対象デバイス
CONConsole

キーボード / ディスプレイ

PRNPrinter

パラレルポート

AUXAuxiliary

シリアルポート

NULNull

データを破棄する仮想デバイス


5. x86命令セットの肥大化

Intelのx86アーキテクチャは、1978年の8086から現在まで一度も命令セットをリセットせず、機能を追加し続けてきた。

  • プレフィックスの乱用: 命令の前に特定のバイト(プレフィックス)を置くことで、16ビット命令を32ビットや64ビットとして解釈させる「ハック」を繰り返してきた。

  • デコードのコスト: 命令長が1バイトから15バイトまで変動するため、CPUが命令を読み取る(デコードする)だけで膨大な電力と回路面積を消費する。これはARMなどのRISCプロセッサに対する弱点となっている。

  • 代償: 数千の命令の中には、もはや誰も使わない8080時代の10進演算補助命令(AAA等)が、バイナリ互換性のためだけに最新のCPUのシリコン上に刻まれ続けている。