computer system foundationCSF 2026
コンピュータの設計 / 03.4

ソフトウェアの
階層構造

トランジスタの ON / OFF から Python の1行まで。ハードウェアとソフトウェアをつなぐ「抽象化の橋」を1枚の図にする。

難易度:★★☆ 所要:25–30分 前提:アーキテクチャ入門
01

抽象化の階段

この講義でこれまで見てきたものは、実は1本の階段の別々の段であった。 下から順に積み上がっていて、それぞれの層は、すぐ下の層のことだけ知っていればいい——それが抽象化である。 各層をクリックすると詳細が開く。

L7
アプリケーション層
Python / Java / JavaScript …
人間が書く高水準プログラム。ゲーム・Web サービス・AI アプリなど。
ハードウェアの詳細を知らなくても開発できるのは、下の層がすべて隠してくれているからである。
例:print("Hello") の1行で、ディスプレイに文字が出る。
L6
ランタイム・標準ライブラリ
libc / glibc / Python runtime …
アプリと OS の間にある「便利な道具箱」。printf()malloc() など。
内部ではシステムコールを呼び出して、OS に仕事を頼んでいる(03 節で見る)。
L5
オペレーティングシステム(OS)
Linux / macOS / Windows …
ハードウェアを管理する「司令塔」。プロセス管理・メモリ管理・ファイルシステム・デバイスドライバ。
アプリは直接ハードウェアを操作できず、必ず OS を通してリソースを要求する。
第4章「オペレーティングシステム」で詳しく学ぶ。
L4
命令セットアーキテクチャ(ISA) ← ハードとソフトの境界
x86-64 / ARM / RISC-V …
ハードウェアとソフトウェアの「契約書」。CPU が理解できる命令の一覧表である。
ADD / MOV / JMP といったアセンブリ命令がこの層に対応する。
ISA が同じなら、内部設計の違う CPU でも同じプログラムが動く——これが互換性の源泉である。 この階段でここだけ特別なのは、上が全部ソフト、下が全部ハードだからである。
L3
マイクロアーキテクチャ(CPU 内部)
パイプライン / キャッシュ / ALU …
ISA の命令を実際に実行する、CPU 内部の設計。Verilog で記述するのがこの層である。
同じ ISA でも各社の内部設計は違う(Intel Core i9 と Apple M4 はどちらも同じアプリが動く)。
第2章の Verilog と、03.1 アーキテクチャ入門で扱ったのがここ。
L2
デジタル論理回路
AND / OR / NOT / Flip-Flop …
ゲートとフリップフロップで構成された回路。第1章で学んだ論理ゲートの世界である。
1億個以上のゲートが、1つの CPU チップに収まっている。
L1
トランジスタ(物理層)
MOSFET / 3nm / 数兆個 …
電圧の ON / OFF でスイッチとして機能する半導体素子。
最新の CPU には 約1,840億個のトランジスタが入っている(Apple M3 Ultra の場合)。
第0章で見たスイッチの歴史が、この層の起源である。
抽象化の意義: 各層が下の層の詳細を隠すことで、上の層の開発者が「下を知らなくていい」状態が作れる。 Python プログラマーはトランジスタを知らなくてよく、CPU 設計者は OS の詳細を知らなくてよい—— これが、1人の人間には到底理解しきれない規模のコンピュータを、それでも人間が作れる理由である。
02

ソースコードが機械語になるまで

L7 で書いたコードは、そのままでは L4(ISA)に届かない。4つの道具が順にバトンを渡していく。 色のついた3つが、実際に変換の仕事をする道具である。

INPUT
ソースコード
C / C++ / Rust
TOOL
コンパイラ
gcc / clang
中間
アセンブリ
.s
TOOL
アセンブラ
as
中間
オブジェクト
.o
TOOL
リンカ
ld
OUTPUT
実行ファイル
a.out / .exe
コンパイラの仕事
  1. 字句解析 — コードをトークンに分割
  2. 構文解析 — 構文木(AST)を構築
  3. 意味解析 — 型チェック・スコープ確認
  4. 中間表現 — 最適化しやすい IR に変換
  5. コード生成 — CPU の命令セットに変換
リンカの仕事

複数の .o ファイルと標準ライブラリを1つの実行ファイルに結合する。

例:printf() の実体は libc.a の中にある。コンパイル時には「後でつなぐ」という参照だけを残し、 リンカが最後につなぎ合わせる。

ローダーの仕事

実行ファイルをメモリに展開し、CPU が実行できる状態にする。OS の一部として動く。

コード領域・データ領域・スタック・ヒープをメモリ上に配置し、プログラムカウンタを先頭命令に合わせた瞬間、 プログラムが動き始める。

具体例で追ってみましょう。a = 1 + 2 という1行が、どう姿を変えていくか。

// C ソースコード
int a = 1 + 2;
; アセンブリ(x86-64)
mov  eax, 1
add  eax, 2
mov  [a], eax
// 機械語(16進数)
B8 01 00 00 00
83 C0 02
89 45 FC

なお、コンパイラが最適化すると、コンパイル時点で 1+2=3 を計算してしまい、 mov [a], 3 の1命令に置き換わることもある(定数畳み込み)。

03

システムコール ― アプリと OS の境界線

L7 のアプリは、ハードウェアに直接触れない。触れるのは L5 の OS だけ。 その間に引かれた唯一の通り道がシステムコールである。

ユーザー空間(User Space)
ブラウザ
音楽プレーヤー
Python スクリプト
制限された権限で動作 — ハードウェアに直接触れない
システムコール インターフェース
アプリが OS に「お願い」できる唯一の窓口
カーネル空間(Kernel Space)
プロセス管理
メモリ管理
ファイルシステム
デバイスドライバ
ネットワーク
セキュリティ
特権モードで動作 — すべてのハードウェアにアクセス可
CPU / メモリ / ディスク / NIC / GPU(物理ハードウェア)

普段書いているコードの裏側で、どんなシステムコールが呼ばれているのかを見てみましょう。

システムコール何を OS に頼むかアプリから見ると
read() / write()ファイル・標準入出力の読み書きprint() の裏で動く
open() / close()ファイルのオープン・クローズopen("file.txt")
fork() / exec()新しいプロセスの生成・プログラム置き換えシェルがコマンドを実行するとき
mmap() / brk()メモリの確保・解放malloc() の裏で動く
socket() / connect()ネットワーク接続HTTP 通信の裏で動く
exit()プログラムの終了を OS に通知終了時に必ず呼ばれる
なぜユーザー空間とカーネル空間を分けるのか: アプリが自由にハードウェアを操作できてしまうと、悪意あるプログラムがメモリ全体を覗いたり、 他のプロセスのデータを書き換えたりできてしまう。 OS が唯一の門番になることで、セキュリティ・安定性・公平なリソース分配が成り立つ。
04

まとめ

抽象化の7層

トランジスタ → 論理回路 → マイクロアーキテクチャ → ISA → OS → ライブラリ → アプリ。各層が下の詳細を隠す。

ISA が境界線

7層のうち ISA だけが特別。ここより上が全部ソフト、下が全部ハード。互換性はこの契約から生まれる。

コンパイルの流れ

コンパイラ → アセンブラ → リンカ → ローダー。この4つを通って、ソースコードが実行される。

システムコールと特権モード

アプリと OS の唯一の境界。ユーザー空間とカーネル空間の分離が、セキュリティと安定性を支える。

この章でハードウェア側は一通り登りきった。次は、階段の L5 —— OS の中身に入っていく。