TurbowarpCPU 機械語の解説メモ

:::note info
cpuの仕組みが知りたい方はnand gameを先にクリアすることをお勧めします。
:::

:::note warn
この記事はnand gameのSoftwareレベルのネタバレを含みます。

この記事に出てくる機械語はわかりやすくするために本来いれるべきではないところにスペースを入れています。
:::
:::note alert
本記事の内容は筆者の理解に基づいており、正確性に欠ける部分があるかもしれません。
:::

# 前置き
このメモでは、以前作成した TurbowarpCPU における機械語（命令セット）の仕様を簡潔に解説する。

# cpuの概要と基礎知識
### cpuについて

このCPUには、**Aレジスタ**と**Dレジスタ**という2つのレジスタがあり、それぞれを変数のように使うことができる

* **Aレジスタ**：
  メモリのアドレスを指定するために使われる。
  数値を一時的に保持することもでる。


* **Dレジスタ**：
  演算などで使うための一時的な記憶場所。
  主に計算やデータのやり取りに使われる。


 
  ---

このCPUでは、以下の3つの変数が使える：

 
**A**：Aレジスタに格納されている値（数値やアドレス）。
 **D**：Dレジスタに格納されている値（演算用のデータ）。
 **\*A**：Aレジスタの値をアドレスとして使い、そのアドレスが指す**メモリの中身**を表す。


 ---

この画像を見ると理解しやすい
![https___qiita-image-store.s3.ap-northeast-1.amazonaws (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3965914/49ea4c5a-e4c9-480c-a75c-a5cb5b79dff6.png)
(Aの値が2なので*Aはアドレスが2ときのメモリの内容を示している)

### コードについて

#### フォーマット
一般的に
**```[ターゲット] = [オペレーション]:[ジャンプ]```**
のような感じで書く(これを二進数に直して入力する)

#### 説明
```ターゲット```演算結果が書き込まれるレジスタ(変数)を指定(省略可能)
```オペレーション```ALU演算処理
```ジャンプ```ジャンプする際の条件を指定(省略可能)

#### サンプルコード
```c
D=0
A=2
D=D+1
0:JMP
```

# 命令の種類&解説
このcpuには大きく二つの命令がある。
## A命令
### フォーマット
```c
0 vvvvvvvvvvvvvvv
```
0からはじまる。
```v```•••格納する値
### 機能
Aレジスタに15ビットの値を格納する。

### サンプルコード
```c
0 000000000000010
```
Aレジスタに2を格納
## C命令
### フォーマット

```c
1 ---- ooooo ttt jjj
```
1から始まる
```-```•••特に意味はない(1でも0でもいい)
```o```•••オペレーション(左から順にu op1 op2 zx sy)
```t```•••ターゲット(左から順にa d *a)
```j```•••ジャンプの種類(左から順にlt eq gt)
### 機能
演算、ジャンプ、レジスタ制御など


### 命令フィールド詳細
<details><summary>オペレーション</summary>

•uは1なら **算術演算** 、0なら **論理演算** 系の命令になる。

•op1、op2はその中(⇑)の命令を区別する。

•zxが1なら入力(XとYの2つのうちX)が0になる。
(値をコピーしたり正負を逆にしたいときなどに使用されるものと思われる)
例: ```A=D```や```D=-D```など

•swが1なら2つの入力を反転させる。(X→Y,Y→Xとして回路に入力される)
例:```D-A```と```A-D```

#### コード
|意味    | u| op1| op2|zx| sw| 
|:-:    |:-:|:-:|:-:|:-:|:-:|
|D+A    | 1 | 0 | 0 | 0 | 0 |
|D-A    | 1 | 1 | 0 | 0 | 0 |
|A-D    | 1 | 1 | 0 | 0 | 1 |
|D+1    | 1 | 0 | 1 | 0 | 0 |
|A+1    | 1 | 0 | 1 | 0 | 1 |
|D-1    | 1 | 1 | 1 | 0 | 0 |
|A-1    | 1 | 1 | 1 | 0 | 1 |
|-D     | 1 | 1 | 0 | 1 | 1 |
|-A     | 1 | 1 | 0 | 1 | 0 |
|-1     | 1 | 1 | 1 | 1 | 1 |
|1      | 1 | 0 | 1 | 1 | 1 |
|D      | 1 | 0 | 0 | 1 | 1 |
|A      | 1 | 0 | 0 | 1 | 0 |
|D(and)A| 0 | 0 | 0 | 0 | 0 |
|D(or)A | 0 | 0 | 1 | 0 | 0 |
|(not)D | 0 | 1 | 1 | 0 | 0 |
|(not)A | 0 | 1 | 1 | 0 | 1 |
|0      | 0 | 0 | 0 | 1 | 0 |






</details>

<details><summary>ターゲット</summary>

•演算の結果を代入する対象のこと。
•```0:JMP```のようにターゲットを省略することは可能。
(この場合0はオペレーション。:JMPはジャンプ命令)

#### コード


|意味| a | d | *a| 
|:-:|:-:|:-: |:-: |
|(void) |  0 |  0  | 0 | 
|A=     |  1 |  0  | 0 | 
|D=     |  0 |  1  | 0 | 
|*A=    |  0 |  0  | 1 | 
|A,D=   |  1 |  1  | 0 | 
|D,*A=  |  0 |  1  | 1 | 
|A,D,*A=|  1 |  1  | 1 | 



</details>
<details><summary>ジャンプ</summary>

•代入(実行)後の値を評価してジャンプするか決める。

•Aレジスタの値がジャンプ先(のアドレス)になる。

•Tとはターゲットの値のこと。

•lt eq gtとは順に **less than（未満）equal（等しい）greater than（より大きい）** という意味であり、比較対象はTと0だ。
(多分 JEQ →Jump EQual、JGE Jump Greater than Equalのというように頭文字がらとったものと思われる。)


#### コード

|アセンブリ名|意味| lt | eq | gt | 
|:-:|:-:|:-: |:-: |:-:|
|(void)|省略| 0  |  0  | 0 | 
|JLT|T <  0| 1  |  0  | 0 | 
|JEQ|T == 0| 0  |  1  | 0 | 
|JGT|T >  0| 0  |  0  | 1 | 
|JLE|T <= 0| 1  |  1  | 0 | 
|JGE|T >= 0| 0  |  1  | 1 | 
|JMP|無条件 | 1  |  1  | 1 | 

サンプルコード

```c
1 0000 11100 010 010 //Dを1減らす。Dが0ならジャンプ
```

</details>

 ---

### サンプルコード
このコードは『コードについて』のサンプルコードを機械語に直したものだ。

```c
1 0000 00010 010 000 //Dレジスターに0をセット。 　C命令
0 000000000000010    //Aレジスターに2をセット。 　A命令
1 0000 10100 010 000 //Dレジスターに1を加える　　 C命令
1 0000 00000 000 111 //無条件ジャンプする。(2行目)C命令
```
このコードでDレジスタのカウンターができる。

# まとめ
この記事が、少しでもCPUや機械語に興味を持つきっかけとなれば幸いだ。