Think Essentially

計算機テクノロジー全般が好きです

【コンピュータシステムの理論と実装】第4章

機械語に理解するために,以下の3つの抽象化についてだけ考えればよい.

1. メモリ

  • コンピュータで,データや命令を保存するハードウェアデバイスを指す
  • 各セルはワードロケーションとも呼ばれ,それぞれはユニークなアドレスを持つ
  • Memory[address], RAM[address], M[address]と表現する

2. プロセッサ

  • プロセッサ = 中央演算装置,central-processing-unit, CPU
  • このプロセッサの演算対象となる値のことをオペランド演算子という.

3. レジスタ

  • register, 登録所,仮置き場みたいな

個人的な例え

メモリ,プロセッサ,レジスタ,ストレージをビュッフェレストランで例える.

個人的な印象として,

  • プロセッサ → ご飯を食べる人
  • レジスタご飯を食べる人のテーブルの上のお皿
  • メモリ → フロアに置いてあるビュッフェ
  • ストレージ → 厨房の冷蔵庫

って感じがする.

長期的に保存する食べ物は冷蔵庫に貯蓄し,その冷蔵庫の中にある食べ物は何らかの処理・加工を施してビュッフェとしてフロアに配置される. ご飯を食べる人はそのビュッフェから一時的に自分のお皿に盛り付け,その食べ物を処理する(食べていく).ご飯を食べる人からすると,ビュッフェは少し遠いもので,直接処理することは出来ない.一方で 机上の食事はすぐ手の届く位置にあり,処理しやすい.

機械語

バイナリコードは,人にとっては暗号めいているため,通常,バイナリコードニーモニックの両方を用いて表される

ニーモニック

ADDとか,基本的に英語三文字の記号のこと.

  • レジスタは基本的にR0, R1, R2 っていう表現をするよ
  • 記号による抽象化によって,コードを読むだけじゃなくて,書くことも出来るようになるよ.
  • 記号による表記をアセンブリ言語っていうよ.単にassemblyっていうこともあるよ
  • アセンブリから機械語に変換するプログラムをassemblerっていうよ
ADD R0, R1, R2 // R0 = R1 + R2
AND R0, R1, R2 // R0 = R1 && R2

メモリアクセス

メモリアクセスを行うコマンドは2種類に分類される

  1. 算術演算,論理演算
  2. 読み込み・格納

1. 直接アドレシング (direct addressing)

アドレスを読み取って,メモリに格納されている情報を読み取る

LOAD R1, 67 // R1 = Memmory[67]
LOAD R1, foo // R1 = Memmory[67] (変数を読み込ませる)

2. イミディエイトアドレッシング (immediate addressing)

定数を読み込む.

LOADI R1, 54 // R1 = 54

3. 間接アドレッシング (indirect addressing)

  • ポインタを扱う際に用いるよ
  • 高水準コード(C言語)における特定の配列を操作する際に用いるよ.
コンパイラの配列操作の仕組みをおさらい
  1. 高水準言語でfooという変数名で配列を宣言し,コンパイラに通す
  2. コンパイラは,その foo と名付けられた 配列データ のメモリ領域(セグメント)を割り振る
  3. セグメント*1のベースを参照する foo という記号を作る

つまり, (高水準言語を書いた)人から見たfoo配列データを指すんだけど, 機械から見たfoo配列データの入口を示すアドレス値を指すんだね

// セグメントのベースアドレスを参照する例
// x = foo[j] もしくは,x = *(foo + j) の変換

ADD R1, foo, j // R1 = foo + j
LOAD R2, R1    // R2 = Memory[R1]
STR R2, x      // x = R2

分岐命令

分岐命令の3つの手段

  • 反復
  • 条件分岐
  • サブルーチン呼び出し
    • 機械語は,プログラムの指定された位置へ戻る手段を持つ必要がある
    • つまり,戻る指標が必要

Hack機械語の仕様

  • Hackコンピュータ = ノイマン型のプラットフォーム

Hack メモリアドレス空間

  • Hackは二つの異なるメモリ空間を持つ
    • 命令メモリ (instruction memory) → 読み込み専用,ROM (read only memory)
    • データメモリ (data memory)
  • 両方とも16bit幅,サイズは32K
  • CPUは,命令メモリだけ読み込める

Hack レジスタ

このHackレジスタを図書館の司書さんで例えてみる.

  • よく動く司書さん → Aレジスタ (以下,A司書さん)
  • あまり働かない司書さん → Dレジスタ (以下,D司書さん)

A司書さんはよく働きます.きびきびと,アドレス(番地)を読み取って,その番地に対応する本棚から本を探して抜き取ります(参照).そして自分で本を持ちます. D司書さんはそんなにきびきび動きません.いちいち動いたり,高い棚にある本を少し背伸びして取るなんて面倒なので,基本的に本を持つことしかしません.Aレジスタさんから「これちょっと持ってて~」と言われて本を持つだけです.

Hack記法

レジスタと同様に2種類の命令から構成されるよ

A命令 (アドレス命令,address instruction)

  • @hoge とかにあたる. 以下の3つの役割を持つ

  • 定数代入

  • メモリ操作
  • 移動命令

C命令 (計算命令,compute instruction)

  • bar;hoge がこれにあたる
  • 111a cccc ccdd djjj というフォーマット
    • 111 → これは C命令だよ,を表す
    • a cccc cc → comp 領域 =「何,どのように計算するのか」
    • dd d → dest 領域 = 「それをどこに格納するのか」→ Aレジスタ or Dレジスタ or Mレジスタ
    • jjj → jump領域 = 「次に何を行うのか」

コードの最小単位は

@hoge
M = 7
  • @hogeなどの@ + 文字列の場合,それはメモリのラベルを表す
  • @7などの@ + 数値の場合,Aに値そのものが入る
  • この2行でA司書さんは,番地を読み取って,その番地に対応する本棚から本を取り出して本を一時的に持ちます

その他やってて思ったこと

  • @hoge などのラベルでも,機械側は結局 @16 とかに変換している
  • 出力をきちんとRAM[2]に指定しないとアカン.テストで気づいた.
  • CPU emulater にて Speed を Max に設定すると なんか楽しい(高速で行ったり来たりする)

*1:セグメント = 領域

test

test

test