植物 植物
初心者講座:擬似命令

AOBA's Information Processing Education



1998/03/08

注意1:このページは、回線を切断した後でゆっくりご覧になってください(テキストを印刷する場合は、その取り扱いに注意してくださるようお願いします)。

注意2:背景が白地の画面を長時間見つめていると頭が痛くなってしまいますので、ここは背景をグレーにしています。


 最初に先週(第16回)の宿題の解答をしましょう。

問題
 GR0の内容が(10進数で)50でAの内容が(10進数で)20の場合、以下の命令を実行するとGR0は(10進数で)いくつになるでしょうか?。
 AND GR0,A

解答
 ANDは第1オペランドと第2オペランドの(ビットごとの)論理積演算を行い、その結果を第1オペランド(つまりレジスタの方...この問題ではGR0)に設定する命令です。
 まずは50と20を2進数に変換して、その(ビットごとの)論理積を求めます(CASLは1語が16ビットですので、16ビットで考えます)。

 (0000000000110010)2=50
 (0000000000010100)2=20

 (0000000000010000)2=50 AND 20

 問題では10進数でいくつかと問われてますので、これを逆に10進数に変換します。

 (0000000000010000)2=24=16

 答えは16です。
 なおCASLでは(というよりほとんどのコンピュータでは)、負数を2の補数で表現します。この問題は両オペランドが正数でしたが、もし負数の場合はそれを2の補数で表現したものと論理積をとらなければなりません。さらに論理積をとった結果、符号ビット(最も左に位置するビット...第0ビット)が1ならば負数と判断して10進数に変換します(2の補数を忘れた方は第7回講座を復習)。

 ここで重要なことは、論理演算命令(AND,OR,EOR)の対象オペランドは16進数(または2進数)に限らないということです。逆に、算術演算命令(ADD,SUB)の対象オペランドは10進数とは限りません。
 この点については擬似命令の一つ、DC命令で学習します。

 ということで、今週は擬似命令についての解説です。

 CASLの命令には大きく分けて3つの命令があります。
 一つ目は機械語命令で、これはCOMETのCPUが解釈して実行する命令です。ロード/ストア命令,算術演算命令,論理演算命令は機械語命令でした。
 二つ目は擬似命令で、これはアセンブラが解釈する命令です。第15回目の講座でちょっと触れたDS命令は擬似命令の一つでした。
 三つ目はマクロ命令ですが、この命令については後の講座で説明します。

 さて、「COMETのCPUが解釈して実行」とか「アセンブラが解釈」とか言われても何のことやら意味不明でしょう。
 実はこの意味を理解するのは初心者にとって非常に難しいのです。
 そこで、ここでは以下のように区別します。

 機械語命令:プログラム実行中に逐次解釈されて実行する命令
 擬似命令:プログラム実行前に1度だけ解釈されている命令

 機械語命令の一つであるADD命令は、両オペランドを加算して、それを第1オペランドに設定する命令です。これはADDを実行する直前に、ADD命令と解釈されて両オペランドの加算が行われます。そして次の命令サイクルで同じように次の命令の解釈と実行が行われます
 対して、擬似命令の一つであるDS命令は領域を確保する命令ですが、領域を確保するのはプログラムの実行中ではありません。プログラムを開始した時点で、すでに当該領域は存在しなければなりません。逆に言えば、DS命令はプログラム実行前に1度だけ解釈されているはずの命令です(これを行うのはアセンブラです)。
 かなり強引な説明ですが、とりあえずはこのように覚えておきましょう。

(注)これが混乱する原因は、同じ”解釈する”という用語をCPUとアセンブラで異なった意味で使用しているからでしょう。一方がハードウェアでもう一方がソフトウェアですからね。でもまあ、そんなことは気にしないのが賢明です。

 次は擬似命令個々についての説明ですが、実はCASLの擬似命令はたった4つしかありません。

(1)START命令(プログラム先頭の定義)
 START命令はプログラムの先頭に必ず記述しなければなりません。そしてSTARTの左側に必ずラベルを付けなければならず、そのラベルがSTART命令以下のプログラムの名前となります。そしてCPUが当該プログラムに実行をかけると、(ほとんどの場合)START命令直後の命令を最初に実行します。

例)
PROG1 START
      ST GR0,SV0
      ST GR1,SV1
      ....(以下省略)

 上記はPROG1というプログラムを定義したものです。

(2)END命令(プログラムの末尾の定義)
 END命令はプログラムの末尾(最終行)に必ず記述しなければなりません。ただし、プログラムの末尾とはプログラムの終了を意味するものではなく、あくまでもプログラムの最終行という意味です(多くの場合、プログラムの途中にプログラムを終了する命令がありますので)。

例)
      ....(以上省略)
      EXIT ; これがプログラムを終了する命令(説明は省略)
SV0   DS 1
SV1   DS 1
      END

(3)DS命令(領域の確保)
 DS命令はオペランドで指定した語数分の領域を確保する命令です。一般にはDSの左側にラベルを記述しますが、ラベルはなくてもOKです(ラベルのないDS命令の使用方法については、今考える必要はありません)。

例)
      ....(以上省略)
      LD GR0,CODE
      ST GR0,DATA
      ....(途中省略)
CODE  DS 1  ; 1語の領域を確保 名前をCODEと付けた
DATA  DS 10 ; 10語の領域を確保 名前をDATAと付けた
      DS 4  ; 4語の領域を確保 名無し
      ....(以下省略)

(注)DS命令に限らないのですが(後述のDCや機械語命令すべて)、プログラムソース上の命令記述順と機械語に展開された後の命令の順番が一致します。だから例のようにDS命令を連続して記述すると、それが連続した領域に取られるのです(上記例ではCODEの直後にDATAがくっついて配置され、合計して15語の領域が確保されます)

(4)DC命令(定数の定義)
 DC命令は、オペランドで指定した値の領域を確保(領域を確保した上に、プログラムの開始に先立って、オペランドで記述した値に初期化する)する命令です。一般にはDCの左側にラベルを記述しますが、ラベルはなくてもOKです。

例)
      ....(以上省略)
      LD GR0,C50   ; GR0の内容が50になる
      LD GR1,HF083 ; GR0の内容が#F083になる
      ....(途中省略)
C50   DC 50   ; 1語を確保し10進数の50で初期化する
CM100 DC −100 ; 1語を確保し10進数の−100で初期化する
HF083 DC #F083; 1語を確保し16進数のF083で初期化する
      DC #93AB; 1語を確保し16進数の93ABで初期化する
      ....(以下省略)

 例にあるように、10進数で表現した定数(1語)を確保する場合は10進数の数値をそのまま記述し、16進数で表現した定数(1語)を確保する場合は#の後に16進数4桁を記述します。
 10進定数や16進定数を確保する場合は、一つのDC命令で必ず1語しか確保されません。また、DCで確保した領域に対してST命令を実行することもできます。ただしこの場合は、元の定数が破壊されることに注意してください。

(注)DC命令はここで説明する10進定数と16進定数の確保以外にもありますが、とりあえずは2つだけ覚えておきましょう。

 10進数と16進数についてもっと詳しく説明しなければなりません。うーん、でもそれは来週にしましょう。
 ではまた。