Mímisbrunnr知恵の泉

← コンピュータ基礎 一覧

🎓 レベル:基礎 | 重要度:A(必須)

📎 前提:OSの役割とカーネル | 関連:仮想記憶とページングメモリ階層とキャッシュ

要点(BLUF)

概念 ── 2種類のアドレス

コンパイルされたプログラムには「変数xは番地0x1000」のようにアドレスが埋め込まれます。でも、複数のプロセスが同時に走るのに、全員が0x1000を物理メモリの同じ場所に書いたら衝突します。

解決は アドレスを2層に分けること。

CPUが論理アドレスでメモリにアクセスするたび、MMUというハードがそれを物理アドレスへ翻訳します。

flowchart LR
    CPU["CPU(論理アドレスを発行)"] --> MMU["MMU(変換)"]
    MMU --> MEM["物理メモリ(DRAM)"]
    OS["OS(変換表を設定)"] -.->|"プロセス切替で表を差し替え"| MMU

要するに、プロセスは「自分用の地図(論理)」で動き、MMUが「実際の住所(物理)」へその場で読み替える。プロセスを切り替えると(プロセスとスレッド)OSが変換表を差し替えるので、同じ論理アドレス0x1000でも別プロセスでは別の物理場所を指します。

仕組み ── 最も単純な変換(ベースとリミット)

歴史的に最も単純な方式がベースレジスタ+リミットレジスタです。

flowchart LR
    la["論理アドレス"] --> chk{"リミット以下?"}
    chk -->|"No"| trap["例外 → OSが介入(不正アクセス)"]
    chk -->|"Yes"| add["+ ベースレジスタ"]
    add --> pa["物理アドレス"]

これで、プロセスを物理メモリのどこに置いてもベースを変えるだけで動き(再配置)、リミットで他人の領域へのはみ出しをハードが強制的に防ぐ(保護)。ただしこの方式は1プロセス=連続した1ブロックを要求するため断片化に弱く、現代はページング仮想記憶とページング)に置き換わりました。考え方の出発点として重要です。

具体例 ── なぜ「自分専用に見える」か

2つのプロセスが同じプログラム(同じ実行ファイル)から起動されると、両方とも論理アドレス上は同じレイアウト(同じ番地にmain関数、同じ番地に大域変数)になります。しかしMMUの変換表が別なので、物理メモリ上では完全に別の場所に展開され、互いに干渉しません。これが「同じプログラムの複数起動」が衝突しない理由です。

仕組みの直観 ── なぜこの間接層を挟むのか

「論理→物理」という余分な変換は一見ムダですが、間接層には絶大な利点があります(計算機科学の万能薬「もう1段の間接参照」)。

⚠️ よくある誤解・落とし穴

対応ラボ

なし(変換の数値は 仮想記憶とページング03-02_address_translation.py で実証)。

関連

第3章 メモリ管理 目次