アセンブリ言語 CASL2 入門
アセンブリ言語ってどういう言語?と思ったことはありませんか?
プログラミングを勉強していて突き当たるのが、メモリやらアドレスやらハード部分の内容。
このハードについて、すぐにイメージできるようにしたいならアセンブリ言語が近道です。
現在のプログラミングは、アセンブリ言語や機械語レベルまで知識を掘り下げる必要がく、「ハード面のイメージいまいち掴(つか)めないな」と悩む人も多いはず。
そこでこの記事では、数あるアセンブリ言語の中でも仕組みが単純な『CASL2』について情報を共有したいと思います。
アセンブリ言語を勉強するデメリット
アセンブリ言語はメモリの動きをイメージできるようになる点で一度は学んで損はない言語です。
しかし、最近ではプログラム言語の進化によってハードウェアの知識がなくてもプログラムを組めるようになりました。
また、ハードの進化で一昔前みたいに効率的なプログラムを組む必要もなくなり、論理的な考え方と言語の使い方が分かれば概ねOKになりました。
したがってコンピューターの知識を他者よりも深めたい以外にメリットがなくなってしまいました。
そして、さらに悲しいお知らせが...。(´;ω;`)
【悲報】CASL2はオワコン?になりました
CASL2が基本情報技術者試験(FE)の問題から除外されることが決まりました。
基本情報技術者試験の午後試験が2023年4月からが大きく変更され、CASL2をはじめCやJAVAなどのプログラム言語選択が廃止されます。
そのため、基本情報技術者を合格するためにCASL2を学んでいた方にとっては、アセンブリ言語を学ぶメリットはなくなってしまいました。
FEではこれまで、擬似言語(アルゴリズムを表現するための擬似的なプログラム言語)と併せて、個別プログラム言語(C、Java、Python、アセンブラ言語、表計算ソフト)による出題を実施してきましたが、普遍的・本質的なプログラミング的思考力を問う擬似言語に統一します。出典:プレス発表 基本情報技術者試験と情報セキュリティマネジメント試験を通年試験化
しかし、アセンブリ言語そのものに興味がある人にとっては関係ないかもしれません。
CASL2を学ぶメリット
基本情報技術者試験からの除外が決まったとはいえ、CASL2はアセンブリ言語の中でも仕組みが単純で初学者向きという大きなメリットがあります。
さらに、CASL2には公式・非公式ともに多くのシミュレーターが存在するので、勉強用のキットを買うことなく無料で学べる点も大きいといえます。
アセンブリ言語に興味がある人たちの間ではオワコンにはならず、しぶとく存続し続けると思います。(笑)
CASL2シミュレーター
↓↓↓
マニアックだから価値がある
アセンブリ言語は皆が興味を示しにくいからこその価値があります。
世の中には無料で役に立つ情報が大量に転がっていますが、人間は楽をしようとしてしまい結局は有益な情報を無視したり、無駄にしています(当方もその一人です...)。
その中にあって
- 高級言語・・・C、JAVA、Python、またはPHPのような人間に分かりやすい仕様のプログラム言語。機械語やアセンブリ言語は低級言語。
Pythonという言語を例にどう役に立つのかというと、Pythonには「ジェネレータ」という特別な動きをする関数があります。
このジェネレータは、データがどんなに大量になってもメモリを圧迫しない強みがあります。
メモリ空間のイメージが鮮明なことで、このジェネレータの使いどころの理解が早まるはずです。
結局は、無駄な知識なんて存在しないのですね。
アセンブリ言語に必要な前提知識
ここからはCASL2について詳しく見ていきます。
CASL2はCOMET2用のアセンブリ言語
CASL2は、COMET2というコンピューターにプログラムするためのアセンブリ言語です。
CASL2を勉強しようとしたときに「COMET2」と「CASL2」という言葉が2つも出てくるため混乱してしまうと思います。
COMET2は基本情報技術者試験のために生み出された架空のコンピューター本体のことで、CASL2はCOMET2の機械語に対応したアセンブリ言語のことです。
【COMET2とCASL2の違い】- COMET2: 基本情報技術者専用に作られたコンピューターの名前
- CASL2: COMET2に対応したアセンブリ言語の名前
コンピューターの動作の仕方
アセンブリ言語を使うときには、基本的なコンピューターの動作原理を理解する必要があります。
特にコンピューターは「メモリ」から「レジスタ」にデータをロードして計算するという定番の動きを知っておくと理解が早かったりします。
レジスタとは、すべてのCPUに必ず備わっている記憶装置で、他のどんな記憶装置よりも速く動作することで知られています。
コンピューターは、大まかに「メモリにデータを設定」→「データをCPUのレジスタに移動」→「計算」→「メモリに計算結果を戻す」の順番で処理が行われています。
【コンピューターの計算順番】- メモリにデータを設定
- メモリに設定されたデータをCPUのレジスタに移動
- 足し算、引き算などの計算処理
- メモリに計算結果を戻す
ニーモニック
ニーモニック(mnemonic)とは、機械語を人間に分かりくアルファベットに置き換えたものです。
※ mnemonicと書いていますが誤字ではないですよ。先頭のmが誤字っぽく見えますよね。
アセンブリ言語そのものを指すという認識でOKです。
機械語は1と0の数列でしかなく、人間が直接機械語でプログラミングしようとすれば大変な労力を強いられます。
目がチカチカするはずです。
そこで登場したのが、ニーモニックです。ニーモニックとは機械語一つ一つに名前を付けたものと考ることができるでしょう。
レジスタ
COMET2のCPUには「汎用レジスタ」「フラグレジスタ」「プログラムレジスタ」「スタックポインタ」の4種類のレジスタが搭載されています。
【レジスタの種類】- 汎用レジスタ
- フラグレジスタ
- プログラムレジスタ
- スタックポインタ
汎用レジスタ
汎用レジスタとは、メモリからロードしたデータを一時的に保存しておくレジスタです。
単に「レジスタ」といった場合には、汎用レジスタのことを示しています。
アセンブリでプログラムを組んでいる内にお馴染みになってくるはずです。
COMET2にはGR0~GR7の8つの汎用レジスタが用意されていて、このレジスタの容量は1語です。
このGRというのは、「General Resister」または「General-purpose Resister」といい、各単語の頭文字をつなげたものです。
汎用的(何にでも使える)レジスタという意味ですね。
- 1語 = 16ビット = 2バイト
CASL2にアキュムレータは存在しない
蛇足になりますが、CASL2には「アキュムレータ(accumulator)」は存在しません。
アキュムレータとは、要するに特別扱いの汎用レジスタのことで、他のアセンブリ言語ではよく登場します。
名前は凄そうですが、単なる汎用レジスタです。(笑)
主にALU(算術論理演算装置)で計算した結果を格納したいときに使用します。
つまり「計算結果かそれ以外か(by R●land)」で呼び分け・使い分けをしているに過ぎません。
CASL2ではデータの扱いを問わず、すべて汎用レジスタにて処理が行われるので「そんなものもあるのか」程度の認識でOKです。
- ALU・・・CPUの中にある計算装置。四則演算(足し算や割り算などの計算)と論理演算はこの装置で行われている。
フラグレジスタ
要領3ビットの小さなレジスタで、ZF(ゼロフラグ)、SF(サインフラグ)、およびOF(オーバーフローフラグ)で構成されています。
フラグレジスタは、ALU(算術論理演算装置)と接続されており、計算結果に応じてそれぞれのフラグが1か0に変化します。
どのような場合にフラグレジスタは動作するのか、例もあわせて見てみます。
- ALU・・・CPUの中にある計算装置。四則演算(足し算や割り算などの計算)と論理演算はこの装置で行われている。
ゼロフラグ
ゼロフラグは、何らかの計算をした結果がゼロであった場合に1に変わります。
- ZF(ゼロフラグ)・・・要領1ビット。計算結果が0のとき1になる。
例1: 引き算の計算をした答えが、0であった場合
【フラグレジスタ】ZF | SF | OF |
1 | 0 | 0 |
ZF(ゼロフラグ)が1になる。
サインフラグ
サインフラグは、何らかの計算をした結果がマイナス(0未満)であった場合に1に変わります。
- SF(サインフラグ)・・・要領1ビット。計算結果がマイナスのとき1になる。
例2: 引き算の計算をした答えが、-1であった場合
【フラグレジスタ】ZF | SF | OF |
0 | 1 | 0 |
SF(サインフラグ)が1になる。
オーバーフローフラグ
オーバーフローフラグは、何らかの計算をした結果が16ビットの容量を超えた(65536以上)であった場合に1に変わります。
- OF(オーバーフローフラグ)・・・要領1ビット。計算結果が16ビットの容量を超えた値のとき1になる。
例3: 足し算の計算をした答えが65536であった場合(16ビットは最大0~65535の範囲でしか数値を表せない)
【フラグレジスタ】ZF | SF | OF |
0 | 0 | 1 |
OF(オーバーフローフラグ)が1になる。
プログラムレジスタ
プログラムレジスタは、現在実行中のプログラムコードが格納されたメモリのアドレスを記憶しておくレジスタです。
別名プログラムカウンタとも呼ばれることがあり、容量は1語です。
専らCOMET2では、「プログラムレジスタ」が正式な呼び名です。
アセンブリを記述する上では特に意識しなくてもOKです。
- 1語 = 16ビット = 2バイト
スタックポインタ
CPU内のレジスタ上のデータをメモリ上のスタック領域に退避させるために使われます。
容量は、プログラムレジスタと同じく1語です。
- 1語 = 16ビット = 2バイト
例えば、プログラムAを実行中に、プログラムBを実行しなければならない状態(割り込み処理)のとき、プログラムBのためにCPUを使わなければなりません。
しかし、CPUはプログラムAが実行中であり、CPU内の汎用レジスタにはプログラムAで使った処理結果が格納されたままです。
そこで、プログラムAの処理内容を何処かに保存するために、このスタックポインタが活躍します。
プログラムAで使っていた汎用レジスタの内容をメモリ上のスタック領域に一時的に保存します。
そのときスタック領域のどのアドレスにデータを保存していったかをスタックポインタに保存しておきます。
それから、プログラムBを呼び出して処理します。
メモリ
メモリは「主記憶装置」のことで、必ずCPUとセットになる装置です。
COMET2においてメモリの容量は65536語(65536 × 2バイト = 131072バイト)で約131キロバイトです。
アドレスは、0~65535番地(0000~FFFF番地)まであります。
つまり、1つの番地に1語のデータを格納できるということになります。
- 1語 = 16ビット = 2バイト
また、メモリはそれぞれ用途に応じて特定の領域に区切られ使用されています。
この65536語の容量中に、実行するためのプログラムコードを格納したり、スタックとして使用する領域も含まれます。
その領域というのが、「プログラム領域」「データ領域」「スタック領域」です。
【メモリの3つの領域】プログラム領域
プログラム領域に格納されているデータは全て機械語として扱われます。
プログラマによって組まれたプログラムコードが格納される領域になります。
前述した「プログラムレジスタ」には、プログラム領域のアドレス値が入っている、ということです。
【プログラム領域】例えば、上の画像の「LAD GR0, 0」という命令を実行中とすると、プログラムレジスタの値は「1」ということになります(「LAD GR0, 0」は1番地に格納されているため)。
データ領域
データ領域は、プログラミングのときに値を設定したり、汎用レジスタからデータがロードしたりストアしたりする領域です。
プログラミングで、メモリといえばデータ領域のことを指しているという認識でOKです。
スタック領域
スタック領域は、データをスタックするために用いる領域です。
スタックは、丁度箱に本を収納するときを想像すると解りやすいでしょう。
一度、収納してしまった本を取り出すとき、最後に入れた本を最初に取り出さないといけませんよね?スタックとはデータをそのような仕組みで取り扱うメモリ上の領域です。
「PUSH」や「POP」などの命令を使用することで、この領域にデータを格納したり取り出したりすることができます。
ターミネーターは旧式のCPUで動いている
ところで、映画『ターミネーター』をご存じですか?
劇中でターミネーターの視点シーンを見ると、何やら赤い画面に英数字がピロピロと動いている様子が描かれています。
実はこのシーンから、ターミネーターのCPUが旧式であることが判明します(笑)。
なぜターミネーターが旧式なのか?
下の画像の黄色い四角で囲ってある部分を見みると、なぜターミネーターが旧式なのかがわかります。
※ 画像は、著作権の関係で映画のシーンをフリー画像で再現したものです。
「ADDR」や「90E0」という文字が見えますが、これはターミネーターに搭載されたメモリ(主記憶装置)のアドレス(ADDR)を表しています。
つまり、画像の90E0という16進数はターミネーターのメモリ上にあるアドレスということになります。
また、この90E0というアドレスは4桁の16進数であることから、ターミネーターは一つの番地の容量が16ビットのメモリを搭載している、と予想できるわけです。
- 16進数4桁 = 16ビット
現在のコンピューターは、CPUもメモリも64ビットなので、16ビットのメモリを搭載しているターミネーターは旧式ということになります。
もちろん、映画の公開が1984年なので、これをつついても仕方ないですよね。(笑)
文法
【文法】
1列目 | 2列目 | 3列目 | ||
ラベル | オペコード | オペランド | ||
第1 | 第2 | 第3 |
上記表に示すように記述します。
オペランドとオペコードを区切るのは「スペース(タブも可)」、第1~第3オペランドを区切るのは「, (カンマ)」です。
【文法の例】- LD GR0, GR1
高級言語と比べ、数少ないアセンブリ言語の利点を挙げるなら、文法が単純だということがいえます。
ラベル、オペコード、オペランドの順番で記述する単純な構成のためです。
ただし、それを何万行と書かなければいけないことが最大の難点といえるでしょう。
オペコード
オペコードとは演算子(オペレーションコード: Operation Code)のことで、どういう処理をさせたいかその動作の種類を記述します。
英語でいう「動詞」の部分に相当します。また、四則演算でいえば、「+」や「×」の記号に相当する部分です。
例えば、英語で、「Add A and B」だと、「AとBを加算しろ」という意味になりますが、アセンブリ言語においても英語の命令文と感覚は一緒です。
【オペコードの例】- LD GR1, GR2 ←このLDの部分です。
LD命令については以下を参考にしてみてください。
オペランド
オペランドとは、被演算子(オペランド: Operand)のことで、計算対象になるデータのことです。
「オペレーションランド」を短縮した言葉ではなく「オペランド」という一つの単語です。
オペコードがオペレーションコードを短縮した呼び方であるためオペランドもそう思われがちですが、実は違うみたいです。
CASL2では、第1~第3までオペランドを指定できます。四則演算の、「A + B」や「A × B」のAやBに相当する部分です。
日本語の「被~」の「被」というのは「~される」という意味を持つ接頭語です。
したがって、被演算子ということは「計算されるもの」ということが分かりますね。
【オペランドの例】- LD GR1, GR2 ←このGR1, GR2の部分です。
ラベル
ラベルは、アドレスに名前をつけるために使用します。
名前をつけると、COMET2が内部でアドレスと名づけたラベルを紐づける作業を行ってくれます。
※ ラベルの長さは8文字までで「GR0~GR7」の汎用レジスタ名は予約語のためラベルとしては使用できません。
コメント文
文法とは関係なしに、プログラムコード上に好きにメモ(文章)を記述できます。
CASL2では「; (セミコロン)」の後に記述します。
ただし、オペコードとオペランドの間やラベルとオペコードの間に書くのはNGです。
そして、記述した文章は、機械語に変換される際に無視されるためプログラム自体に影響を及ぼすことはありません。
プログラムを書いて、後で見て分かり難いと感じる行にやりたいことをメモしておいてもいいでしょう。
文字コード表の見方
コンピューターは、文字コード表を参照してから、ディスプレイに文字を表示する方法をとっています。
以下の文字コード表は「JIS-X-0201」と呼ばれるもので、CASL2で入出力される文字はこのコード表が使用されます。
文字コード表の読み方は「列番号 行番号」の順番で知りたい文字を表しています。
例えば、下記表から「A」という文字を文字コードとして表したいなら「41」ということになります。
【文字コード表】文字「B」であれば文字コードは「42」、文字「K」であれば文字コードは「4B」ということになります。ここで、文字「K」の文字コード「4B」の「B」は「11」という数字を表しています。
アルファベットの「B」は、16進数で「11」を表す数字のため、このような記述になります。ちなみに16進数は、「A、B、C、D、E、F」の順番で「10、11、12、13、14、15」の数字が対応しています。
おすすめのシミュレータ
「公式のシミュレーターが使いずれえ...」という方はは以下のサイト様に載せられているフリーソフトがおすすめです。
このソフトは個人的に使い勝手がいいです。
↓↓↓
ちなみに、すぐに動作を確認したい場合はWEB上で動作する「キャッスルシミュレータ - Web版シミュレータ」もあります。
↓↓↓
さいごに
今回は、アセンブリ言語CASL2について必要な内容を共有しました。
そもそもコンピューターについて慣れていないうちは、難しく感じるかもしれません。
まずは「まだ詳しくは知らないけど、CPUにはレジスタがあるのね」くらいから覚えていけばOKですから、ゆっくり学んでみてください。
それでは次回にお会いしましょう。