サンダーボルト

相手モンスターを全て破壊する。

動かしてわかるCPUの作り方10講

モチベーション

動かしてわかるCPUの作り方10講という本で勉強することになった。せっかくだから学んだことをメモしておきたい。

勉強メモ

第1講

#include <stdio.h>
 
int main()
{
  int res = 0;
  __asm__ volatile("movq $0xffffffff0000007b,%%rax"
                  :"=a"(res));
  printf("%d\n", res);
  return 0;
}
  • GCC : GNU Compiler Collectionの略でで、C、C++、Goとかのコンパイラとかライブラリが入っているもの
  • gcc hello.cでa.outというバイナリが生成される
  • gcc -c hello.cとすればhello.oというオブジェクトファイルが生成される
  • オブジェクトファイルはバイナリの前の中間ファイルで、機械語バイナリ以外にもシンボルテーブルやコメントやメタデータなどが含まれることがある
  • リンカでオブジェクトファイルどうしをまとめてリンクすると1つのバイナリを生成できる
    • a.cとb.cがあり、aがbのメソッドを利用している場合に、a単独ではコンパイルは失敗するが、オブジェクトファイルの生成だけなら失敗しない。その後リンクすればいい。 -アセンブリ言語の文法はシンプル。「命令 オペランド1, オペランド2」命令はオペレーションとも呼ばれ、mov、addなど。ニモニック(mnemonic)と呼ばれる。
  • コンピュータの基本構成はメモリ、CPU、I/O。
  • コンピュータの5大装置
    • 演算装置:CPU
    • 制御装置:CPU
    • 記憶装置:メモリ
    • 入力装置:キーボード
    • 出力装置:ディスプレイ
  • アセンブリ言語機械語と対応しており、オペレーション(命令)の種類は5大装置と関係がある。演算命令、制御命令などがある。
  • CPUはALU(Arithmetic Logic Unit)や汎用レジスタなどがか構成される
  • ALU : 算術論理演算装置。論理演算、加算、減算などを行う。👇はwikipediaの画像。こういうVみたいな記号がちょいちょい出てくる
    f:id:nao_666:20210612163223p:plain
    ALU
  • レジスタ : CPUなどに入っている記憶素子で、最も高速な記憶装置。機械語を読み込む専用のインストラクション・レジスタ(IR)と汎用レジスタが存在する。

第2講

  • シンプルな命令セットをもつRISC(Reduced Instruction Set Computer)と複雑なCISC(Complex Instruction Set Computer)がある
  • 今回設計するCPUについて
    • 命令、オペランドを含めて15bitの固定長命令
    • データは16bitで表現する。必然的に汎用レジスタやメインメモリのデータ領域のデータ長も16bitになる。ALUも16bitが基本サイズ(?)
    • ハーバードアーキテクチャを採用。ノイマンアーキテクチャは単一メモリ方式(命令とデータをどちらも同じメモリに柔軟に配置)。対してハーバードアーキテクチャでは命令とデータをそれぞれ別のメモリに配置するようにする。(キャッシュへの経路を2つ用意する)参考
    • レジスタとメインメモリ間のデータ転送は
      • インストラクションレジスタ↔プログラム領域
      • 汎用レジスタ↔データ領域
      • で行われるが、今回命令長は15bit、データ長は16bitとしてので、1bit違う。なので楽に実装するためにこれらを別のデータバスとして扱うハーバードアーキテクチャにする。
    • メモリマップドI/Oを採用。入出力装置のコマンドレジスタとデータレジスタを直接見る(I/Oマップド)のではなく、入出力装置に命令を出す際も他と同様にメインメモリを利用する。メモリマップドI/Oでは、アセンブリ言語で書いた際にI/Oのために特別な命令を使わないのでI/O接続していることがわかりづらい。参考

第3講

  • flagはレジスタではないのか?実態はなんなんだ...

第4講

  • カルノー図を使えば最も簡単な論理式を導ける
  • 組み合わせ回路:入力と出力が1:1で対応する
  • 順序回路:内部状態を持っており、出力が過去の入力にも依存する