【基本情報技術者試験】アセンブラ（CASL II）について

## はじめに
2019年秋に基本情報技術者試験を受験し合格していました。その時に「アセンブラ」について色々とメモしていたので、今更ながらこちらに公開したいと思います

## アセンブラとは…
意味としては以下の2つを指す

 - アセンブリ言語のプログラムを機械語のプログラムに変換するソフトウェア
 - アセンブリ言語

## 特徴
 - 低水準言語（高水準言語にはJava, Cなどがある）
 - 低水準言語は機械語に近く、高水準言語は人間語に近い
 - メモリが少なくても大丈夫だったりする

## 基本情報技術者試験で扱われているCASLとは…
 - 情報処理技術者試験でのプログラム能力試験で使用するために作られたアセンブリ言語

## 事前に知っておくと良い単語


|単語|意味|
|:------|:-------------|
|COMET Ⅱ|仮想的なコンピュータ。ここで動くプログラムを書くための言語がCASL Ⅱ。|
|アセンブル|アセンブリ言語で書かれたプログラムを機械語に変換すること|
|レジスタ|CPU内部の記憶装置|
|汎用レジスタ|記憶装置の一種。演算結果やメモリアドレスの格納に使われる|
|オペランド|数値や変数などのデータ|
|フラグレジスタ（FR）|オーバーフローフラグ(OF)、サインフラグ(SF)、ゼロフラグ(ZF)などの情報を保持するレジスタ|
|インデックス修飾アドレッシング|アドレス部と指標レジスタ部分の値を加算してアドレスを指定する方式|
|実行アドレス|処理対象のアドレス|
|指標レジスタ|アドレスを示す指標のメモリ。CASLⅡの場合はGR1~GR7まで使用できる|
|オーバーフロー|演算結果が取り扱い範囲を超えること|
|オーバーフローフラグ|演算結果がオーバーフローしたかどうかを示す|
|サインフラグ(SF)|演算結果の符号ビットが設定されるフラグ|
|ゼロフラグ(ZF)|演算結果が0になったものを表すフラグ。演算結果が0になった場合はZFは1に、それ以外はZFは0に設定される|
|チェックサム|データの合計値がおかしくなっていないかチェックする誤り検出符号の一つ|
|パリティ|データ内にある1の個数がおかしくなっていないかチェックする誤り検出の一つ|
|マスク|ビット演算において、ビット単位の操作を行う処理|

## 雛形

（";”が書いてある行はコメント）

```hoge.cas
プログラム名 START
           RPUSH
           ; 実質的なプログラムの記述。LD命令やLAD命令など
           RPOP
           RET
           ; DS命令、DC命令などを書く
           END
```

## 文法や命令ついて

それぞれの列の意味は以下。先ほどの雛形を例にするとプログラム名部分がラベル、命令コード部分がSTARTになる。オペランドとは、数値や変数などのデータのことでLD命令やLAD命令、DS命令などで指定する場合が多い

```
ラベル 命令コード オペランド
```

一文目にかかれている名前はプログラムの名前で、どういう処理を行うかに応じて名前を決める。注意点として、ラベルを書く際には

 - 1文字以上8文字以下
 - 先頭文字はアルファベット、2文字目以降はアルファベットまたは数字

にする必要がある

```
; 例）合計金額を求めるプログラム

SUM START
      :
      :
```

## 命令一覧

### 値の読み込みや保存に関する命令

|命令|意味|
|:-----------------|:------------------|
|START命令|STARTと書いた行から実行開始する命令 |
|NOP命令|何もしない命令。なんで何もしない命令を書くのか？→プログラムの処理が早くてもうちょっと処理を遅くしたい場合や後に命令を追加するために使われているらしい。|
|RET命令|リターン命令。プログラムの動作を終了させる|
|END命令|プログラムの記述を終了させる命令|
|LAD命令|ロードアドレス命令。指定された値を指定した汎用レジスタに設定する|
|ST命令|ストア命令。汎用レジスタに設定してある値を汎用レジスタとは別の主記憶装置にコピーする|
|DS命令|オペラント部で指定した数値分、主記憶上に領域を確保する|
|DC命令|オペラント部の値を1度だけ主記憶に設定する命令|
|LD命令|ロード命令。命令の種類としては3つある。①指定した主記憶上のアドレスに格納されている値を指定した汎用レジスタにコピーする②右側の汎用レジスタの値を左側の汎用レジスタにコピーする③第二項と第三項で指定した値を加算して汎用レジスタに|
|IN命令|キーボードで入力した文字を主記憶に格納する命令|
|OUT命令|オペランドで指定した範囲の文字を画面に表示する命令|

### 演算に関する命令
|命令|意味|
|:------|:-------|
|ADDL命令|加算を行う命令|
|SUBL命令|減算を行う命令|
|ADDA命令|加算する値を符号付の数値と考えて加算を行う命令|
|SUBA命令|符号付数値として減算を行う命令|
|SLL|論理左シフトを行う命令|
|SRL|論理右シフトを行う命令|
|SLA|算術左シフトを行う命令|
|SRA|算術右シフトを行う命令|

### 比較命令
|命令|意味|
|:-----|:-------|
|CPL命令|オペランドの値を符号なし数値として比較し、フラグレジスタ（FR）に値を設定する|
|CPA命令|オペランドの値を符号つき数値として比較し、フラグレジスタ(FR)に値を設定する|

### 条件分岐命令
|命令|意味|
|:-----|:-------|
|JZE命令|ゼロ分岐命令。ZFが1、つまり演算結果が0の時指定のラベル行にジャンプする命令|
|JPL命令|SF=1かつZF=0の場合に分岐する命令。演算結果が正の場合に分岐|
|JMI命令|SF=1の場合に分岐する命令。演算結果が負の場合に分岐|
|JNZ命令|ZF=0の場合に分岐する命令。演算結果がゼロでなかった場合に分岐|
|JOV命令|OF=1の場合に分岐する命令。演算結果でオーバーフローが発生した場合に分岐|
|JUMP命令|必然的に分岐する命令|

### 命令の種類は以下の三つに分類できる
- 機械語命令
- アセンブラ命令
- マクロ命令

### その他
|命令|意味|
|:-----|:-------|
|CALL命令|副プログラムを呼び出す命令|
|PUSH命令|汎用レジスタの値をスタックに積む命令|
|POP命令|スタックに積んである値を汎用レジスタに取り出す命令|


- GR0~GR7→汎用レジスタ。汎用レジスタは0~7の8個がある
- 数値の頭に#と書くと16進数であることを示している。数値の先頭に何もつけないと10進数表記
- LD命令とLAD命令の違いは、主記憶にアクセスするかしないかの違い。LD命令では主記憶上のアドレスを指定し、そのアドレスに格納されている値を汎用レジスタにコピーするが、LADは指定した値をそのまま汎用レジスタにコピーする
- シングルクオーテーションで囲われた文字は、文字コードに変換され、主記憶に格納される
- 算術シフトと論理シフトの違いとして、算術シフトは符号ビットが動かないが、論理シフトは動くという点
- 2の補数の求め方としてはビット反転させて1を足す

## 参考
- プログラミング入門 CASL2―情報処理技術者テキスト