2018-06-01
更新 2020-10-01

アセンブリ言語のCASL2 入門







ハリウッド映画「ターミネーター」をご存じでしょうか。劇中で、サイボーグが主人公とヒロインを追いかけるシーンがありますが、実はこのシーンにアセンブリ言語と機械語の演出を見ることができます。

しかも、その機械語は16ビットのようで、未来から来たターミネーターのはずが旧式のCPUを搭載しているのか、と面白い事実に気づくことができます。もちろん、映画が公開された1984年当時のコンピューターが参考になっているはずですから当然ですね(笑)。

本記事では、「基本情報技術者」の午後試験の「CASL2」について触れます。










アセンブリがおすすめの理由



アセンブリがおすすめの理由は、他のC言語やJAVAよりも簡単で、事前に仕様を知っていれば試験本番で理解しなければならない内容が少なくて済む点です。

CASL2は、「COMET2」という架空のコンピューターを動作させるために考案されたアセンブリ言語で、教育用としてコンピューターの動作原理を受験者が理解しているかを見極めるためのものという認識で問題ありません。

出題内容そのものは単純であるため、事前にCASL2の仕様を把握していれば問題を解きやすいといえます。しかし、簡単とはいっても他者によって書かれたプログラムを読めるようになるためには、ある程度の慣れが必要で誰でも初めは「難しい...」と感じてしまうはずです。

もちろん、理解しようと努めていれば、必ずコードを理解できる瞬間が来るため、諦めないことが大切になってきます。このように、プログラミングは、習得できるまでに乗り越えなくてはならない思考の壁が存在するため、誰でも簡単に行える作業ではないことが分かるでしょう。

つまり、プログラミングとは一種のスキルであり、能力が身につけばお金を生む代物になるといえます。




アセンブリを使う前に必要な知識



アセンブリ言語に限らず、プログラミングを学ぶ前にはある程度のコンピューターの動作について知っておく必要があります。ここではCASL2やコンピューターの動作原理について触れます。



CASL2はCOMET2用のアセンブリ言語



CASL2は、COMET2というコンピューターにプログラムするためのアセンブリ言語です。

基本情報技術者でアセンブリを勉強しようとしたときに、「COMET2」と「CASL2」という言葉が2つも出てくるため混乱してしまうと思います。

COMET2は基本情報技術者試験のために生み出された架空のコンピューター本体のことで、CASL2はCOMET2の機械語に対応したアセンブリ言語のことです。

【COMET2とCASL2の違い】
  • COMET2・・・基本情報技術者専用に作られたコンピューターの名前
  • CASL2・・・COMET2に対応したアセンブリ言語の名前



COMET2の仕様







コンピューターの動作原理



アセンブリ言語を使う際には、基本的なコンピューターの動作原理を理解する必要があります。

特に、コンピューターは「メモリ」から「レジスタ」にデータをロードして計算する、という動作原理を知っておく必要があり、言ってしまえば、これさえ分かっていれば十分ともいえます。レジスタとは全てのCPUに必ず備わっている記憶装置で、他のどんな記憶装置よりも速く動作することで知られています。

コンピューターは、「メモリにデータを設定」→「データをレジスタに移動」→「計算」→「メモリに計算結果を格納」の順番でレジスタにデータを移動させてから計算することを覚えておくと、アセンブリを理解しやすくなるでしょう。

【コンピューターの計算順序】
  1. メモリにデータを設定
  2. 1. で設定されたデータをレジスタに移動
  3. 足し算、引き算などの計算
  4. メモリに計算結果を格納









レジスタ



COMET2のCPUには「汎用レジスタ」「フラグレジスタ」「プログラムレジスタ」「スタックポインタ」の4種類のレジスタが備わっています。

【レジスタの種類】
  1. 汎用レジスタ
  2. フラグレジスタ
  3. プログラムレジスタ
  4. スタックポインタ



汎用レジスタ



汎用レジスタとは、メモリからロードしたデータを一時的に保存しておくレジスタです。

単に「レジスタ」といった場合には、汎用レジスタのことを指しています。数あるレジスタの中でも、最も頻繁にデータの書き換えが行われ、アセンブリでプログラムを組んでいる内にお馴染みになってくるレジスタです。

COMET2にはGR0~GR7の8つの汎用レジスタが用意されていて、このレジスタの容量は1語です。このGRというのは、「General Resister」の各単語の頭文字だけ繋げたもので、汎用的(何にでも使える)なレジスタという意味になります。

※ 1語とは、16ビット(=2バイト)のことです。



フラグレジスタ



要領3ビットの小さなレジスタで、ZF(ゼロフラグ)、SF(サインフラグ)、およびOF(オーバーフローフラグ)で構成されています。

フラグレジスタは、汎用レジスタとも接続されており、常に汎用レジスタ上での値の変化を監視しているといっても間違いではありません。

CASL2では、足し算や引き算などの計算を行った後に、答えが汎用レジスタに戻されるため、汎用レジスタとフラグレジスタが接続されていることで、適切にフラグを立てることができます。どのような場合にフラグレジスタは動作するのか、例も併せて見てみましょう。



ゼロフラグ



ゼロフラグは、何らかの計算をした結果がゼロであった場合に1に変わります。

  • ZF(ゼロフラグ) ・・・要領1ビット。計算結果が0のとき1になります。

例1: 引き算の計算をした答えが、0であった場合

【フラグレジスタ】
ZFSFOF
100

ZF(ゼロフラグ)が、1になります。



サインフラグ



サインフラグは、何らかの計算をした結果がマイナス(0未満の数値)であった場合に1に変わります。

  • SF(サインフラグ)・・・要領1ビット。計算結果がマイナスのとき1になります。



例2: 引き算の計算をした答えが、-1であった場合

【フラグレジスタ】
ZFSFOF
010

SF(サインフラグ)が、1になります。



オーバーフローフラグ



オーバーフローフラグは、何らかの計算をした結果が16ビットの容量を超えた(65535以上の数値)であった場合に1に変わります。

  • OF(オーバーフローフラグ) ・・・要領1ビット。計算結果が16ビットの容量を超えた値のとき1になります。



例3: 足し算の計算をした答えが、65536であった場合(16ビットは最大0~65535の範囲でしか数値を表せない)

【フラグレジスタ】
ZFSFOF
001

OF(オーバーフローフラグ)が、1になります。



プログラムレジスタ



プログラムレジスタは、現在実行中のプログラムコードが格納されたメモリのアドレスを記憶しておくレジスタです。

別名プログラムカウンタとも呼ばれることがあり、容量は1語です。専らCOMET2では、「プログラムレジスタ」が正式な呼び名です。アセンブリを記述する上では、特に意識しなくてもOKです。



スタックポインタ



CPU内のレジスタ上のデータをメモリ上のスタック領域に退避させるために使われます。

容量は、プログラムレジスタと同じく1語です。例えば、主プログラムを実行中に、副プログラムを実行しなければならない状態(割り込み処理)が発生したとき、副プログラム実行のために、CPUを使わなければなりません。

しかし、CPUは主プログラムが実行中であり、CPU内の汎用レジスタには主プログラムで使った処理結果が格納されたままです。そこで、主プログラムの処理内容を何処かに保存するために、このスタックポインタが活躍します。

主プログラムで使っていた汎用レジスタの内容を、メモリ上のスタック領域に一時的に保存しておきます。そのときに、スタック領域のどのアドレスにデータを保存していったかを、スタックポインタに保存しておきます。

それから、副プログラムを呼び出して処理が終わると、CPUは、スタックポインタを参照して、主プログラムの内容を各レジスタに戻し、主プログラムの処理を再開します。このレジスタもアセンブリを記述する上では、特に意識しなくてもOKです。




メモリ





メモリは、「主記憶装置」のことであり、必ずCPUとセットになる装置です。

COMET2においてメモリの容量は65536語(65536 × 2バイト = 131072バイト)。すなわち、約131キロバイトです。アドレスは、0~65535番地(0000~FFFF番地)まであります。つまり、1つの番地に1語(16ビット)のデータを格納できるということになります。



加えて、メモリはそれぞれ用途に応じて特定の領域に区切られ使用されています。この65536語の容量中に、実行するためのプログラムコードを格納したり、スタックとして使用する領域も含まれます。その領域というのが、「プログラム領域」「データ領域」「スタック領域」です。

なお、「データ領域」が、さらに「静的領域」と「ヒープ領域」に分ける場合もありますが、CASL2はアセンブリ言語であり、グローバル変数とローカル変数を区別する仕様ではないため、データ領域で統一しても問題ありません。

【図1: メモリの3領域】




プログラム領域



プログラム領域に格納されているデータは全て機械語として扱われます。

プログラマによって組まれたプログラムコードが格納される領域になります。前述した「プログラムレジスタ」には、プログラム領域のアドレス値が入っているということになります。

【図2: プログラム領域】


例えば、図2上の「LAD GR0, 0」という命令を実行中とすると、プログラムレジスタの値は「1」ということになります(「LAD GR0, 0」は、1番地に格納されているため)。



データ領域



データ領域は、プログラミングするときに値を設定したり、汎用レジスタからデータがロードされる領域です。

プログラミングにおいてスタックを意識的に使用する場合を除いて、メモリといえばデータ領域のことを指していると捉えて差し支えないでしょう。



スタック領域



スタック領域は、データをスタックするために用いる領域です。

スタックは、丁度箱に本を収納するときを想像すると解りやすいでしょう。一度、収納してしまった本を取り出すとき、最後に入れた本を最初に取り出さないといけませんよね?スタックとはデータをそのような仕組みで取り扱うメモリ上の領域です。

「PUSH」や「POP」などの命令を使用することで、この領域にデータを格納したり取り出したりすることができます。同命令は、唯一スタックのデータを扱うことのできる命令になります。








文法



文法
ラベルオペコードオペランド
第1第2第3

上記表に示すように記述します。

オペランドとオペコードを区切るのは「スペース(タブも可)」、第1~第3オペランドを区切るのは「, (カンマ)」です。

【文法の例】
  • LD GR0, GR1

高級言語と比べ、数少ないアセンブリ言語の利点を挙げるなら、文法が単純だということがいえます。ラベル、オペコード、オペランドの順番で記述する単純な構成のためです。ただし、それを何万行と書かなければいけないことが最大の難点といえるでしょう。



オペコード



オペコードとは演算子(オペレーションコード: Operation Code)のことで、どういう処理をさせたいかその動作の種類を記述します。

英語に例えると「動詞」の部分に相当します。また、四則演算でいえば、「+」や「×」の記号に相当する部分です。

例えば、英語で、「Add A and B」だと、「AとBを加算しろ」という意味になりますが、アセンブリ言語においても英語の命令文と感覚は一緒です。

【オペコードの例】
  • LD GR1, GR2 ←このLDの部分です。




オペランド



オペランドとは、被演算子(オペランド: Operand)のことで、計算対象になるデータのことです。

「オペレーションランド」を短縮した言葉ではなく、「オペランド」という一つの単語です。オペコードがオペレーションコードの短縮した呼び方であるため、オペランドにも適用されると思われることがありますが間違いです。

CASL2では、第1~第3までオペランドを指定できます。四則演算の、「A + B」や「A × B」のAやBに相当する部分です。

日本語の「被~」の「被」というのは「~される」という意味を持つ接頭語です。したがって、被演算子ということは、「計算されるもの」ということが分かります。

【オペランドの例】
  • LD GR1, GR2 ←この「GR1, GR2」の部分です。



ニーモニック



ニーモニックとは、機械語を人間に分かりくアルファベットに置き換えたものです。

アセンブリ言語そのものを指すという認識で問題ありません。機械語は1と0の数列でしかなく、人間が直接機械語でプログラミングしようとすれば、大変な労力を強いられます。

そこで登場したのが、ニーモニックです。要するに、ニーモニックとは機械語に名前を付けたもの、と考ることができるでしょう。



ラベル



ラベルは、アドレスに名前をつけるために使用します。

名前をつけると、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版シミュレータ」もおすすめです。

↓↓↓

キャッスルシミュレータ - Web版シミュレータ

何れも、全く同じ動作をしています。各シミュレータにおいてレジスタの仕様に差異は特に見当たりませんでした。



最後に



今回は、CASL2を扱う上で必要な内容を説明いたしました。そもそもコンピューターに慣れていない内は、難しく感じるかもしれません。まずは、「まだ詳しくは知らないけど、CPUにはレジスタがあるのね」くらいから覚えていけば大丈夫でしょう。












プロフィール

ニッシー
詳細プロフィールへ
お問い合わせへ

こんにちは。ITネタブログの管理人のニッシーです。