プロセッサアーキテクチャとは?CISC・RISC・アドレス指定・割り込みを基礎から理解しよう
はじめに
コンピュータの中心で、プログラムの命令を実行しているのがプロセッサです。
一般的なコンピュータでは、CPU(Central Processing Unit:中央処理装置)がその代表です。
プロセッサは単純に「計算をする装置」ではありません。
主記憶から命令を取り出す
↓
命令を解読する
↓
必要なデータを取得する
↓
演算する
↓
結果を保存する
という処理を高速に繰り返しています。
この記事では、
- プロセッサの種類
- CISCとRISC
- プロセッサの構成
- プログラムのロード
- 命令の実行
- オペランドとアドレス指定方式
- ビッグエンディアンとリトルエンディアン
- ウォッチドッグタイマ
- 割り込み制御
について学んでいきます。
1. プロセッサとは
**プロセッサ(Processor)**とは、
プログラムに書かれた命令を解釈して、演算や制御を行う装置
です。
代表的なものがCPUです。
CPUは主記憶に格納されたプログラムを読み出し、
命令を読む
↓
意味を解釈する
↓
演算する
↓
結果を保存する
という処理を繰り返します。
2. プロセッサの種類
用途によって、さまざまな種類のプロセッサがあります。
CPU
**CPU(Central Processing Unit)**は、一般的なコンピュータの中心となるプロセッサです。
OSやアプリケーションなどの命令を実行します。
GPU
**GPU(Graphics Processing Unit)**は、もともと画像処理を高速に行うために発展したプロセッサです。
多数の演算を並列に処理することを得意としており、現在では画像処理だけでなくAIなどの大量の並列演算にも利用されています。
DSP
**DSP(Digital Signal Processor)**は、デジタル信号処理に特化したプロセッサです。
音声・画像・通信信号などの処理に利用されます。
マイクロコントローラ
**マイクロコントローラ(Microcontroller)**は、
- CPU
- メモリ
- 入出力機能
などを一つのチップにまとめたものです。
家電や自動車、IoT機器などの組込みシステムで広く利用されています。
3. プロセッサの方式
プロセッサの命令セットの考え方として代表的なのが、
- CISC
- RISC
です。
どちらも、
CPUにどのような命令を用意するか
という設計思想に関係しています。
4. CISC
**CISC(Complex Instruction Set Computer)**とは、
複雑で高機能な命令を含む、多くの命令を持たせる考え方
です。
一つの命令で比較的複雑な処理を行えるようにします。
イメージすると、
1命令
↓
複数の処理をまとめて実行
という考え方です。
CISCの特徴
- 命令の種類が多い
- 複雑な命令を持つ
- 命令長や実行時間が一定とは限らない
- 一つの命令で複雑な処理を実現できる
代表的な命令セットとして、x86系があります。
5. RISC
**RISC(Reduced Instruction Set Computer)**とは、
命令を比較的単純なものに絞り、高速に実行しやすくする考え方
です。
複雑な処理は、単純な命令を組み合わせて実現します。
単純な命令
↓
単純な命令
↓
単純な命令
↓
目的の処理
RISCの特徴
- 命令の種類を比較的単純にする
- 命令形式を単純化しやすい
- パイプライン処理と相性がよい
- レジスタを積極的に利用する
代表的な命令セットにはARMやRISC-Vなどがあります。
6. CISCとRISCの違い
| 項目 | CISC | RISC |
|---|---|---|
| 正式名称 | Complex Instruction Set Computer | Reduced Instruction Set Computer |
| 命令 | 複雑な命令を含む | 比較的単純 |
| 命令種類 | 多い傾向 | 絞り込む傾向 |
| 命令形式 | 複雑になりやすい | 単純化しやすい |
| パイプライン | 複雑になりやすい | 適用しやすい |
| 代表例 | x86系 | ARM、RISC-Vなど |
🍯 「CISC=複雑な仕事も1命令で」「RISC=単純な命令を高速に組み合わせる」くらいから覚えると分かりやすいです。
なお、現在のプロセッサでは両者の技術を取り入れている場合も多いため、完全に二分できるわけではありません。
7. プロセッサの基本構成
CPUの内部には、主に次のような構成要素があります。
┌─────────────────┐
│ CPU │
│ │
│ 制御装置 │
│ ↓ │
│ 演算装置(ALU) │
│ │
│ レジスタ群 │
└─────────────────┘
↕
主記憶
制御装置
命令を解読し、CPU内部の各装置へ指示を出します。
演算装置
**ALU(Arithmetic Logic Unit)**などが、
- 加算
- 減算
- AND
- OR
- 比較
といった算術・論理演算を行います。
レジスタ
CPU内部にある高速な記憶領域です。
処理中のデータやアドレス、命令などを一時的に保持します。
8. 代表的なレジスタ
プログラムカウンタ
**PC(Program Counter)**は、
次に実行する命令のアドレス
を保持します。
命令レジスタ
**IR(Instruction Register)**は、
現在実行している命令
を保持します。
汎用レジスタ
計算途中のデータやアドレスなどを一時的に保持します。
9. プログラムのロード
プログラムは通常、SSDなどの補助記憶装置に保存されています。
しかし、CPUがプログラムを実行するときは、必要なプログラムを主記憶へロードします。
SSDなど
↓
プログラムをロード
↓
主記憶
↓
CPUが命令を取得
つまり、
保存は補助記憶、実行時は主記憶
という関係が基本です。
10. 命令の実行
CPUは基本的に、
- 命令フェッチ
- 命令デコード
- オペランド読出し
- 命令実行
- 結果格納
という流れで処理します。
① 命令フェッチ
プログラムカウンタが示しているアドレスから命令を読み出します。
PC
↓
主記憶
↓
命令を取得
② 命令デコード
取得した命令が、
加算なのか?
転送なのか?
比較なのか?
などを制御装置が解読します。
③ オペランド読出し
命令の処理対象となるデータを取得します。
④ 命令実行
ALUなどを使って実際の処理を行います。
⑤ 結果格納
演算結果をレジスタや主記憶などへ格納します。
そして次の命令へ進みます。
11. 命令とオペランド
CPUの命令は概念的には、
命令コード + オペランド
として考えることができます。
例えば、
ADD 100
という命令があったとします。
ADD が、
加算する
という処理内容を示す**命令コード(オペコード)**です。
一方の 100 は、
何を対象にするか
を表すオペランドです。
12. アドレス指定方式とは
オペランドに必要なデータの場所を指定する方法を、
アドレス指定方式(Addressing Mode)
といいます。
代表的なものとして、
- 即値アドレス指定
- 直接アドレス指定
- 間接アドレス指定
- インデックスアドレス指定
- ベースアドレス指定
- 相対アドレス指定
があります。
応用情報では、
最終的にどのアドレスのデータを参照するのか
を考える問題が重要です。
13. 即値アドレス指定
**即値アドレス指定(Immediate Addressing)**では、
命令の中にデータそのものを指定します。
例えば、
ADD 10
で 10 自体を加算する値として扱うイメージです。
命令
┌─────┬─────┐
│ ADD │ 10 │
└─────┴─────┘
↑
データそのもの
メモリからオペランドを読み出す必要がないため、単純です。
14. 直接アドレス指定
**直接アドレス指定(Direct Addressing)**では、
命令のアドレス部に、データが格納されている主記憶のアドレスを直接指定します。
例えば、
アドレス部 = 1000
なら、
命令
↓
1000番地
↓
データ
となります。
したがって実効アドレスは、
実効アドレス = 命令のアドレス部
です。
15. 間接アドレス指定
**間接アドレス指定(Indirect Addressing)**では、
命令で指定された場所に、目的データそのものではなく目的データのアドレスが格納されています。
例えば、
命令のアドレス部 = 1000
1000番地 → 5000
5000番地 → データ
なら、
命令
↓
1000番地
↓
5000
↓
5000番地
↓
目的データ
となります。
つまり、一度メモリなどからアドレスを取得して、そのアドレスを使って目的のデータへアクセスします。
16. インデックスアドレス指定
**インデックスアドレス指定(Indexed Addressing)**では、
命令のアドレス部にインデックスレジスタの値を加えて実効アドレスを求めます。
実効アドレス
= アドレス部 + インデックスレジスタ
例えば、
アドレス部 = 1000
インデックスレジスタ = 20
なら、
1000 + 20
= 1020
したがって、
1020番地
を参照します。
配列など、連続したデータを扱うときに便利です。
17. ベースアドレス指定
**ベースアドレス指定(Base Addressing)**では、
ベースレジスタの値に命令のアドレス部を加えて実効アドレスを求めます。
実効アドレス
= ベースレジスタ + アドレス部
例えば、
ベースレジスタ = 5000
アドレス部 = 100
なら、
5000 + 100
= 5100
となります。
プログラムやデータを主記憶上の異なる場所へ配置するときなどに利用できます。
18. 相対アドレス指定
**相対アドレス指定(Relative Addressing)**では、
プログラムカウンタなどの値に命令のアドレス部を加えて実効アドレスを求めます。
実効アドレス
= PC + アドレス部
例えば、
PC = 2000
アドレス部 = 50
なら、
2000 + 50
= 2050
となります。
現在の命令位置を基準として目的の場所を指定できるため、分岐命令などで利用されます。
19. アドレス指定方式を整理しよう
| 方式 | 基本的な考え方 |
|---|---|
| 即値 | 命令中にデータそのもの |
| 直接 | アドレス部が目的データのアドレス |
| 間接 | アドレス部が指す場所に、さらに目的データのアドレス |
| インデックス | アドレス部+インデックスレジスタ |
| ベース | ベースレジスタ+アドレス部 |
| 相対 | PCなど+アドレス部 |
🍯 「即値=値そのもの」「直接=住所」「間接=住所が書かれた場所」「インデックス=配列」「ベース=基準位置」「相対=現在位置からの距離」とイメージすると整理しやすいです。
20. 主記憶上のデータのバイト順序
複数バイトのデータを主記憶へ格納するとき、
どのバイトから先に格納するか
というルールがあります。
これを**エンディアン(Endian)**といいます。
代表的なのが、
- ビッグエンディアン
- リトルエンディアン
です。
21. ビッグエンディアン
**ビッグエンディアン(Big Endian)**では、
上位バイトから低いアドレスへ格納します。
例えば、
0x12345678
という32ビットデータなら、
低アドレス
↓
1000 : 12
1001 : 34
1002 : 56
1003 : 78
↓
高アドレス
となります。
人間が16進数を書く順番と同じように見えるため、比較的直感的です。
22. リトルエンディアン
**リトルエンディアン(Little Endian)**では、
下位バイトから低いアドレスへ格納します。
同じ、
0x12345678
なら、
低アドレス
↓
1000 : 78
1001 : 56
1002 : 34
1003 : 12
↓
高アドレス
となります。
23. ビッグエンディアンとリトルエンディアン
比較すると、
データ:0x12345678
ビッグエンディアン
低アドレス → 12 34 56 78 → 高アドレス
リトルエンディアン
低アドレス → 78 56 34 12 → 高アドレス
です。
🍯 「ビッグ=大きい桁(上位バイト)から」「リトル=小さい桁(下位バイト)から」と覚えると分かりやすいです。
なお、エンディアンはバイトを並べる順序の話です。
24. ウォッチドッグタイマ
**ウォッチドッグタイマ(Watchdog Timer)**とは、
コンピュータが正常に動作しているか監視するためのタイマ
です。
システムが正常なら、プログラムは一定時間ごとにウォッチドッグタイマをリセットします。
正常動作
↓
定期的にタイマをリセット
↓
正常動作
↓
またリセット
ところが、プログラムが暴走したり停止したりすると、
プログラム異常
↓
タイマをリセットできない
↓
タイムアウト
↓
異常を検出
↓
システムをリセット
といった処理ができます。
組込みシステムなど、長時間安定して動作する必要があるシステムで重要です。
25. 割り込みとは
CPUがプログラムを実行している途中で、
別の重要な処理を行う必要が発生する
ことがあります。
そこで使われるのが、
割り込み(Interrupt)
です。
割り込みとは、
実行中の処理を一時中断し、必要な処理を優先的に実行する仕組み
です。
26. 割り込みの仕組み
例えばCPUが処理Aを実行している途中で割り込みが発生したとします。
処理Aを実行
↓
割り込み発生!
↓
現在の実行状態を保存
↓
割り込み処理を実行
↓
保存した状態を復元
↓
処理Aを再開
ここで重要なのが、
元の処理を後から再開できるように状態を保存する
ことです。
保存対象には、
- プログラムカウンタ
- レジスタ
などがあります。
ソフトウェア篇で学んだコンテキストにもつながる考え方です。
27. 割り込みの種類
割り込みは大きく、
割り込み
├─ 内部割り込み
└─ 外部割り込み
に分類できます。
28. 内部割り込み
**内部割り込み(Internal Interrupt)**とは、
CPUが実行している命令などに起因して発生する割り込み
です。
例えば、
- 0による除算
- オーバーフロー
- 不正な命令
- ページフォールト
- システムコールなどによるソフトウェア割り込み
などがあります。
CPU内部の命令実行に関連して発生するため、内部割り込みと呼ばれます。
29. 外部割り込み
**外部割り込み(External Interrupt)**とは、
CPUの外部にある装置などを原因として発生する割り込み
です。
例えば、
- キーボード入力
- 入出力装置の処理完了
- タイマ
- ハードウェア異常
などがあります。
例えばディスクへの入出力を考えてみましょう。
CPUがディスク処理の完了までずっと待っていると、その時間が無駄になります。
そこで、
CPU
↓
ディスクへ処理を依頼
↓
CPUは別の処理を実行
↓
ディスク処理完了
↓
割り込み!
↓
CPUが完了処理を実行
とすることで、CPUを効率よく利用できます。
30. 内部割り込みと外部割り込み
| 種類 | 発生原因 | 例 |
|---|---|---|
| 内部割り込み | 実行中の命令などCPU内部の処理 | 0除算、不正命令、ページフォールトなど |
| 外部割り込み | CPU外部の装置など | 入出力完了、タイマ、ハードウェア異常など |
🍯 「内部=実行している処理が原因」「外部=外の装置などから呼ばれる」と考えると整理しやすいです。
31. プロセッサアーキテクチャの全体像
今回の内容をつなげてみましょう。
プロセッサ
│
├─ 種類
│ ├─ CPU
│ ├─ GPU
│ ├─ DSP
│ └─ マイクロコントローラ
│
├─ 命令セットの設計思想
│ ├─ CISC
│ └─ RISC
│
├─ CPU内部
│ ├─ 制御装置
│ ├─ ALU
│ └─ レジスタ
│
├─ 命令実行
│ ├─ フェッチ
│ ├─ デコード
│ ├─ オペランド読出し
│ ├─ 実行
│ └─ 結果格納
│
├─ アドレス指定
│ ├─ 即値
│ ├─ 直接
│ ├─ 間接
│ ├─ インデックス
│ ├─ ベース
│ └─ 相対
│
├─ データ格納
│ ├─ ビッグエンディアン
│ └─ リトルエンディアン
│
├─ 異常監視
│ └─ ウォッチドッグタイマ
│
└─ 割り込み
├─ 内部割り込み
└─ 外部割り込み
一つひとつ別々に見えますが、
プログラムを主記憶へロード
↓
CPUが命令をフェッチ
↓
命令をデコード
↓
アドレス指定方式から
オペランドの場所を特定
↓
命令を実行
↓
必要に応じて割り込み処理
↓
次の命令へ
と考えると、CPUがどのようにプログラムを実行しているのかが見えてきます。
まとめ
この記事で覚えること
- プロセッサはプログラムの命令を解釈・実行する
- CPU、GPU、DSP、マイクロコントローラなどの種類がある
- CISCは複雑な命令を含む多くの命令を持たせる考え方
- RISCは比較的単純な命令を組み合わせる考え方
- CPUは制御装置、演算装置、レジスタなどから構成される
- プログラムは実行時に主記憶へロードされる
- 命令はフェッチ、デコード、オペランド取得、実行などの流れで処理される
- 即値指定では命令中に値そのものを持つ
- 直接指定ではアドレス部が目的データのアドレスを示す
- 間接指定では指定先にさらに目的データのアドレスがある
- インデックス指定はアドレス部+インデックスレジスタ
- ベース指定はベースレジスタ+アドレス部
- 相対指定はPCなど+アドレス部
- ビッグエンディアンは上位バイトから低アドレスへ格納する
- リトルエンディアンは下位バイトから低アドレスへ格納する
- ウォッチドッグタイマはシステムの異常を監視する
- 割り込みでは現在の処理を一時中断して別の処理を実行する
- 内部割り込みは実行中の命令などに起因する
- 外部割り込みは入出力装置などCPU外部の要因で発生する
🍯 はちみつメモ
CPUは「命令を取る → 解読する → データを探す → 実行する」を繰り返す装置。アドレス指定方式では「最終的にどの番地を参照するのか」を追いかけるのがコツ! エンディアンは「ビッグ=上位から、リトル=下位から」、割り込みは「いったん中断 → 割り込み処理 → 元へ戻る」で覚えよう。