国が実施している情報処理技術者試験において、 受験者に公平にアセンブラの問題を出す為に考え出された仮想のコンピュータがCOMET2。 COMET2のアセンブラ言語がCASL2。 恐ろしくシンプルだが、その分、コンピュータの基本的な動作が理解出来る。 試験のアセンブラ言語は時代に応じて仕様が変更されており、これは三代目。 初代はコンピュータがCOMP-XでアセンブラがCAP-X、 二代目がコンピュータがCOMETでアセンブラがCASL。 私が第一種を受験した時は二代目のCASLになって数年目の時でした。
COMETやCASLを理解する事で、本格的なプログラムを作ろうとか、 一流のゲームプログラマになろうとか考える人はまずいないだろうと思いますが、 コンピュータの仕組みを理解するには、良く出来た言語だと私は思っております。
詳しくは公式マニュアルをお読みください。
以下は雰囲気だけのざっくりとした説明です。
1語は16bit
語はコンピュータ内部で一つのデータとして操作する大きさの単位。
COMET2では16bitで表現出来るデータを単位として処理をすることが出来る。
16bitのそれぞれにはビット番号が付けられており、右端から、0,1,2,3...14,15となっている。
1語のデータは、符号ありの整数(負数は2の補数)、符号なしの整数、および文字コードとして扱う事が出来るが、
どれで扱うかは人間が注意して処理しなければならない。
文字コードは、JIS X 0201 のものを基本とするが、
これは8bitの文字コードであるため、ビット番号の8~15には0が入る。
アドレスバスは16bit
アドレスバスは主記憶装置のアドレスを指定するための並列な経路のこと。
16bitで表現出来る数のアドレス(0番地~65535番地)を直接指定する事が出来る。
それぞれのアドレスには、一語のデータを記憶出来る大きさの領域がある。
データバスは16bit
データバスはコンピュータ内部でデータをやりとりするための並列な経路のこと。
16bitの大きさのデータを一度にやりとり出来る。
汎用レジスタ 16bit
レジスタは、CPU内部にあるデータの記憶領域。
CPUがデータを処理する際に汎用的に使用するレジスタ。
GR0からGR7までの、8つがある。
指標レジスタ 16bit
命令のアドレス部で指定したアドレスから○番目のアドレスのデータ、というように、
配列の添字などの様に使う事が出来るレジスタ。
汎用レジスタのうち、GR1からGR7までの7つを指標レジスタとして使うことが出来る。
CASL2では、アドレスの次に書くレジスタがこれにあたる。
基本的には前述の様な使い方をするが、命令によって、色々と姑息な(?)使い方がある。
プログラムレジスタ 16bit
主記憶装置には命令やデータが記憶されているが、
プログラムレジスタは、次に実行すべき命令のアドレスを記憶しているレジスタ。
命令は基本的にはアドレスの昇順に実行されるが、
命令の大きさが一語(1アドレス分)のものと二語(2アドレス分)のものがあるため(*1)、
一語のときは+1、二語のときは+2される。
また、分岐命令など、離れたアドレスに記憶されている命令に飛ぶ場合は、
分岐先のアドレスが記憶される。
※命令アドレスレジスタ、命令カウンタ、プログラムカウンタ、逐次制御カウンタ、命令ポインタ、など、
色々な言い方が有るので、結構面倒臭いレジスタ。
スタックポインタ 16bit
スタック領域は、主記憶装置の何処かの範囲(COMET2では明示されていない)にある、後入れ先出しの領域。
作業中のデータを記憶しておいたり、
プログラム間でデータの値やデータの有るアドレスを受け渡したり、
副プログラム(サブルーチン)の実行が終了した際に
主プログラムの続きの命令があるアドレスを記憶しておいたりする。
スタックポインタは、最初はスタック領域の最も大きいアドレス+1を記憶しているが、
スタック領域にデータを記憶する際には、
スタックポインタから1を減算して、そのアドレスにデータを記憶し、
スタック領域からデータを取り出す際には、
スタックポインタが記憶しているアドレスからデータを取り出した後、1を加えた値に変更される。
つまり、スタックポインタは、スタック領域内で取り出されていない最後に記憶したデータのアドレスを記憶している。
フラグレジスタ 3bit
特定の命令を実行した際の結果の状態を、1ビットの0か1かであらわすレジスタ。
旗を上げたり下げたりに似ているので、こう呼ばれる。
COMET2では、
結果が表現出来るデータの範囲を超えたか否かをみるオーバーフローフラグ(OF)、
結果が負か否かをみるサインフラグ(SF)、
結果がゼロか否かをみるゼロフラグ(ZF)、の3ビットがある。
分岐命令は、フラグレジスタの状態を元に判断している。
基底アドレスレジスタ(参考)
午後のアセンブラの試験には出て来ないが、午前の知識の試験には出て来るので参考までに。
アセンブラプログラムの中でアドレスを指定する際に、実際にそのアドレスでしか処理が出来ないのは、
主記憶装置に多くのプログラムを同時に実行したり、同じプログラムを複数実行する場合、非常に不味いことになる。
そこで、プログラムをアセンブルする際には、
プログラム中のアドレスの指定はそのプログラムの先頭からの相対的なアドレスにしておき、
プログラムを主記憶装置に配置し実行する際に、
プログラムの先頭の実際のアドレスを基底アドレスレジスタに記憶し、
実際にアクセスするアドレスを、
基底アドレスレジスタの値+命令のアドレス部の値(相対的なアドレス)+必要に応じて指標レジスタの値、
で求めることで、プログラムを主記憶上に自由に配置することが出来る。
この様なプログラムを再配置可能(リロケータブル)なプログラムと言う。
入出力制御
COMET2では、
標準的な入力インタフェースとしてキーボード、
標準的な出力インタフェースとしてディスプレィを想定している。
入出力の際のデータは文字コードとして扱われるため、
例えば、入力された数字でそのまま計算したり、計算結果の数値をそのまま出力したりすると、
滅茶苦茶になる。
(*1)
試験問題には関係しないが、参考資料として、命令は、
命令部(オペランド部)が8bit、レジスタの指定が2つで各4bit、で、これで合わせて1語だが、
主記憶装置のアドレスを指定する場合は、その為にもう1語が必要になる設計になっている。
詳しくは公式マニュアルをお読みください。
以下は雰囲気だけのざっくりとした説明です。
ラベル
アセンブラ言語でプログラムを書く際、
プログラマは、分岐先やデータの記憶場所が何番地になるのか、なんて一々考えたくないし、
しかも、プログラムを書き換える度に番地は変わるし、
どうせなら味気ない数字よりも判りやすい名前の方が良い。
そこで、プログラムを書く際には、目印として番地の代わりにラベルを付けておき、
アセンブラはアセンブルする際にそのラベルが何番地になるのかを計算して
番地に付け替えてくれる様になっている。
論理~/算術~
論理~は、1語のデータを符号なしの数値、文字コード、或いはビット列とみなして処理を行なうこと。
算術~は、1語のデータを符号ありの数値(負数は2の補数)とみなして処理を行なうこと。
両者を混乱して処理を行なうと、とんでもない結果になるので、物凄く注意が必要。
マクロ
物凄く乱暴に言うと、ワープロの短文登録の様なもの。
よく使う一連の命令を名前を付けて定義しておき、
プログラム中で、定義した名前を書いておくと、
アセンブルの際に、引数も含めて、元の一連の命令に展開してくれる。
実行時に副プログラムの様に呼び出して使う訳ではない。
CASL2では、
入力装置(キーボードを想定)から入力されたデータ(文字コード)を読み込むIN、
出力装置(ディスプレィを想定)へデータを文字コードとして出力するOUT、
GR1からGR7までのデータを順にスタック領域へ記憶させるRPUSH、
スタック領域のデータを順にGR7からGR1までのレジスタに記憶させるRPOP、
の4つのマクロがあらかじめ定義されている。