➕
算術回路:加算器・2の補数・減算の実装
論理ゲートで足し算・引き算を実装する方法。半加算器・全加算器・リプルキャリーアダー・2の補数による減算まで。CODE第2版 Ch.14-16。
論理ゲートで足し算をする
前のdocで論理ゲート(AND・OR・XOR)が揃った。これで加算回路を作れる。
1ビット + 1ビット の場合:
二進数の1桁加算:
0 + 0 = 0 桁上がり(キャリー)なし
0 + 1 = 1 キャリーなし
1 + 0 = 1 キャリーなし
1 + 1 = 10 → 下の桁: 0、キャリー: 1
一般化すると:
結果の1桁目 = A XOR B
キャリー = A AND B
半加算器(Half Adder)
キャリーの入力を考慮しない、最も単純な加算回路。
【半加算器の回路】
A ─┬──[XOR]──→ 和(Sum)
│
B ─┤──[AND]──→ キャリーアウト(Cout)
真理値表:
A B │ Sum Cout
0 0 │ 0 0
0 1 │ 1 0
1 0 │ 1 0
1 1 │ 0 1
記号:
┌──────┐
A─┤ HA ├─ Sum
B─┤ ├─ Cout
└──────┘
「半加算器」という名前は、キャリーインを処理できない(半分の機能)ことに由来。
全加算器(Full Adder)
前の桁からのキャリー(Cin)も取り込める完全な加算回路。
【全加算器の回路(半加算器2個 + OR1個)】
A ──┐
├─[HA]─ S1, C1 ─┐
B ──┘ ├─[HA]─ Sum
Cin ───┘ │
C2
C1 ─────────────────────────[OR]─ Cout
実装のポイント:
1つ目のHA:A と B を加算 → S1, C1
2つ目のHA:S1 と Cin を加算 → Sum, C2
最終キャリー:C1 OR C2
真理値表:
A B Cin │ Sum Cout
0 0 0 │ 0 0
0 0 1 │ 1 0
0 1 0 │ 1 0
0 1 1 │ 0 1
1 0 0 │ 1 0
1 0 1 │ 0 1
1 1 0 │ 0 1
1 1 1 │ 1 1
記号:
┌──────┐
A─┤ ├─ Sum
B─┤ FA ├─ Cout
C─┤ │
└──────┘
リプルキャリーアダー(Ripple Carry Adder)
全加算器を縦に並べると、複数ビットの加算ができる。4ビット版の例:
【4ビット加算器】
A3 B3 A2 B2 A1 B1 A0 B0
│ │ │ │ │ │ │ │
Cin ─→[FA3]─→C─[FA2]─→C─[FA1]─→C─[FA0]─→ Cout
│ │ │ │
S3 S2 S1 S0
↑ キャリーが右から左へ「波のように伝播」= Ripple
S3 S2 S1 S0 = 結果(4ビット)
例:0101(5) + 0110(6) を計算
FA0: 1+0+0=1 Sum=1, Cout=0
FA1: 0+1+0=1 Sum=1, Cout=0
FA2: 1+1+0=0 Sum=0, Cout=1
FA3: 0+0+1=1 Sum=1, Cout=0
結果: 1011 = 11 ✓
Ripple(波及) という名前は、キャリーが下位ビットから上位ビットへ順番に伝わる様子から。8ビットなら FA0→FA7 と順番にキャリーが決まるため、ビット数が増えると遅くなる。
オーバーフロー
加算結果がビット数を超えるとき。
【8ビット符号なし整数のオーバーフロー】
11111111 (255)
+ 00000001 ( 1)
─────────────
100000000 → 9ビット!
8ビットに収まらない → キャリーアウトが 1 になる
8ビット部分だけ見ると: 00000000 = 0(間違った答え)
検出方法:
符号なし → Cout(キャリーアウト)が 1 になったらオーバーフロー
符号あり → 正+正=負 または 負+負=正 になったらオーバーフロー
2の補数:減算を加算で実現するトリック
CPUは基本的に加算回路しか持たない。減算は「負の数を足す」ことで実現する。
2の補数の作り方
任意の数 N の「2の補数」= 2^n - N (n はビット数)
8ビットで 5 の2の補数:
2^8 - 5 = 256 - 5 = 251 = 11111011(2)
もっと簡単な計算方法:
① すべてのビットを反転(NOT)
② 1を加える
5 = 00000101
① 反転: 11111010
② +1: 11111011 ← これが -5 の2の補数表現
確認:
5 + (-5) = 00000101 + 11111011
= 100000000
= 0 (下位8ビット) + Cout=1 → 正しく 0 になる
符号付き整数の範囲
8ビット符号付き整数(2の補数):
00000000 = 0
00000001 = 1
...
01111111 = 127 ← 最大値
10000000 = -128 ← 最小値(最上位ビットが符号ビット)
10000001 = -127
...
11111110 = -2
11111111 = -1
表現範囲:-128 〜 +127(合計256通り)
n ビット符号付き整数の範囲:
最小: -2^(n-1)
最大: 2^(n-1) - 1
8ビット: -128 〜 127
16ビット: -32768 〜 32767
32ビット: 約-21億 〜 約21億
64ビット: 約-9.2京 〜 約9.2京
減算の実装
A - B = A + (-B) = A + (Bの2の補数)
回路の実装:
1. B のすべてのビットを XOR-1 で反転(NOT)
2. 加算器の Cin に 1 を入力
→ Bの反転 + 1 = 2の補数 が自動的に計算される
┌────────────────────────┐
│ A3 A2 A1 A0 │
│ │
│ B3 B2 B1 B0 → [NOT] → B̄3 B̄2 B̄1 B̄0
│ │
│ Cin=1 ─────────────────────────────┘
│ ↓
│ [4ビット加算器(Cin付き)]
└────────────────────────┘
ADD/SUB の切り替えは「Cinに何を入れるか」と「Bを反転するか」だけ。
ALU への伏線
加算器と2の補数の仕組みを組み合わせると、加算・減算が一つの回路でできる。
さらに AND・OR・NOT・XOR 演算も追加すると「算術論理演算装置(ALU)」になる。
ALU の入力:
A ← オペランド1
B ← オペランド2
操作コード(何をするか):
000 = ADD
001 = SUB
010 = AND
011 = OR
100 = XOR
101 = NOT A
...
ALU の出力:
結果
ゼロフラグ(結果が0かどうか)
キャリーフラグ(桁あふれ)
オーバーフローフラグ
負フラグ(符号ビット)
これが CPU の核心部品。次の章で記憶(フリップフロップ・RAM)を学んだあと、CPU の組み立てに進む。
- 1. 📖CODE:コンピュータのからくり — シリーズ概要
- 2. 📡信号とコード:点字・モールス・情報伝達の原理
- 3. ⚡電気とリレー:懐中電灯から論理ゲートへ
- 4. 🔢数の体系:2進数・16進数・ASCIIからUnicodeへ
- 5. ➕算術回路:加算器・2の補数・減算の実装
- 6. 💾記憶と時計:フリップフロップ・クロック・RAM
- 7. 🖥️CPUの構造:ALU・レジスタ・バス・制御信号
- 8. 🖥️OSとプログラミング:機械語から高水準言語まで
出典: https://www.amazon.co.jp/dp/4296080245