Top Banner
- - 1 2システム システム システム システム COMET COMET COMET COMETⅡの仕様 仕様 仕様 仕様 ここでは、情報処理推進機構(IPA)が発行している情報処理技術者試験の パンフレットにある「アセンブラ言語の仕様」にそって説明していきます。 この資料では「システム COMETⅡの仕様」の中に命令の説明がかれており、 「アセンブラ言語 CASLⅡの仕様」には命令の説明は記載されていません。 何か奇異な感じがしますが、アセンブラの命令はハードウェア命令そのもの であるので、このような構成になっているのです。
30

2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、...

Jan 10, 2019

Download

Documents

truongdien
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 1

2222章章章章

システムシステムシステムシステム COMET COMET COMET COMETⅡⅡⅡⅡのののの仕様仕様仕様仕様

ここでは、情報処理推進機構(IPA)が発行している情報処理技術者試験の

パンフレットにある「アセンブラ言語の仕様」にそって説明していきます。

この資料では「システム COMETⅡの仕様」の中に命令の説明が書かれており、

「アセンブラ言語 CASLⅡの仕様」には命令の説明は記載されていません。

何か奇異な感じがしますが、アセンブラの命令はハードウェア命令そのもの

であるので、このような構成になっているのです。

Page 2: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 2

■■■■ 2.1 2.1 2.1 2.1 ハードウェアハードウェアハードウェアハードウェアのののの仕様仕様仕様仕様

情報処理推進機構(IPA)の説明書によれば、ハードウェアの仕様として、(1)から(6)まで説明が書

かれています。以下、順に説明していきます。

2.1.12.1.12.1.12.1.1 語語語語

(1) 1(1) 1(1) 1(1) 1 語語語語はははは 16161616 ビットビットビットビットでででで,,,,そのそのそのそのビットビットビットビット構成構成構成構成はははは,,,,次次次次のとおりであるのとおりであるのとおりであるのとおりである。。。。

コンピュータのメモリーの最小単位は「ビット」で、「1ビット、2ビット、・・・」というふうに数えます。

1ビットは「1」か「0」かの2種類の情報を表現できますが、このままでは使いにくいので、いくつかの

ビットをまとめて使うことにしています。

CASLⅡの場合は、16 ビットをひとつの「かたまり」としてあつかい、この「あつまり」を「語1」と呼んでい

ます。

この「語」は単にメモリーの区切り(グループ化)だけに使用するのではなく、後述する「汎用レジス

タ」の大きさも同様にしてあります。

2.1.22.1.22.1.22.1.2 主記憶主記憶主記憶主記憶

(2) (2) (2) (2) 主記憶主記憶主記憶主記憶のののの容量容量容量容量はははは 65536655366553665536 語語語語でででで,,,,そのそのそのそのアドレスアドレスアドレスアドレスはははは 0 0 0 0 ~~~~ 65535 65535 65535 65535 番地番地番地番地であるであるであるである。。。。

上記(1)で説明した「語」が集まってコンピュータのメモリー(主記憶)を形成しています。

COMETⅡでは、この主記憶の大きさが 65536 語あって、各語には 0~65535 までの 65536 個の「名

前」がつけられています。

図図図図 2222----1111 ビットビットビットビット・・・・語語語語・・・・主記憶主記憶主記憶主記憶

この「名前」を「番地(アドレス)」と呼んでいます。

65536 という数字は「中途半端な数字だな~」と感じるかもしれませんが、この数字はちょうど 2 の 16

乗になるのです。

では、なぜ「16乗」なのかといいますと、(5)で説明するように、汎用レジスタの大きさが 16ビットであ

るところから来ています。

では、メモリーが 65536語以上ある場合はどうでしょうか。残念ながら COMETⅡでは、65536以上は使

用することができないのです。理由は 2 章の「実効アドレス」のところで説明します。

2.1.32.1.32.1.32.1.3 数値数値数値数値

(3) (3) (3) (3) 数値数値数値数値はははは,,,,16161616 ビットビットビットビットのののの 2222 進数進数進数進数でででで表現表現表現表現するするするする。。。。負数負数負数負数はははは,,,,2222 のののの補数補数補数補数でででで表現表現表現表現するするするする。。。。

この説明は 1 章で行いました。

2.1.42.1.42.1.42.1.4 制御方式制御方式制御方式制御方式

(4) (4) (4) (4) 制御方式制御方式制御方式制御方式はははは逐次制御逐次制御逐次制御逐次制御でででで,,,,命令語命令語命令語命令語はははは 1111 語長又語長又語長又語長又はははは 2222 語長語長語長語長であるであるであるである。。。。

「逐次制御」と書くと難しそうですが、要するに「命令を順番に実行していく」というもので、ごくアタリ

1 *「語」は「ご」と発音しますが、呼びにくいとかとカッコ良くないなどの理由から「ワード」と呼ばれることもあります。

ビット 語 主記憶 16 集まって 65536 集まって

Page 3: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 3

マエの話です。

しかし、自動制御や携帯電話などのプログラムは逐次制御ではありません1。

アセンブラは(機械語は)命令の形でメモリーに順序良く格納されています。COMETⅡではこの命令

の長さが、1語または2語2ということですので、1語(=16ビット)で表現される命令と、2語(=32ビット)

で表現される命令の、2 種類があるということです。

このあたりは、第 4 章で詳しく説明します。

2.1.52.1.52.1.52.1.5 レジスタレジスタレジスタレジスタ

レジスタレジスタレジスタレジスタのののの種類種類種類種類

(5) (5) (5) (5) レジスタレジスタレジスタレジスタとしてとしてとしてとして,,,,GRGRGRGR((((16 16 16 16 ビットビットビットビット),),),),SPSPSPSP((((16 16 16 16 ビットビットビットビット),),),),PRPRPRPR((((16 16 16 16 ビットビットビットビット),),),),FRFRFRFR((((3 3 3 3 ビットビットビットビット))))のののの 4 4 4 4 種類種類種類種類があるがあるがあるがある。。。。

アセンブラでは、計算やデータのコピーなどは、すべて「レジスタ」と呼ばれるモノ(ハード)を介して

行われます。この説明は次項で。

汎用汎用汎用汎用レジスタレジスタレジスタレジスタ

GRGRGRGR((((汎用汎用汎用汎用レレレレジスタジスタジスタジスタ,,,,General RegisterGeneral RegisterGeneral RegisterGeneral Register))))はははは,,,,GR0 GR0 GR0 GR0 ~~~~ GR7 GR7 GR7 GR7 のののの 8888 個個個個がありがありがありがあり,,,,算術算術算術算術,,,,論理論理論理論理,,,,比較比較比較比較,,,,シフトシフトシフトシフトなななな

どのどのどのどの演算演算演算演算にににに用用用用いるいるいるいる。。。。

アセンブラでは何の処理を行うにも汎用レジスタを経由します。

たとえば、

「変数 A の内容を変数 B へ転送する」

という処理の場合、

C 言語 b=a;

COBOL MOVE B TO A.

と記述します。

しかし、アセンブラでは直接変数間で転送を行うことができず3、次の順序で処理をします。

①汎用レジスタへ変数 A の内容を持ってくる(ロードする)

②汎用レジスタの内容を変数 B へ格納する(ストアする)

図図図図 2222----2222 アセンブラアセンブラアセンブラアセンブラでのでのでのでの変数変数変数変数ののののコピーコピーコピーコピー

この例では、転送(コピー)するデータの長さが1語なので、上記のような対応で済みますが、データ

の長さが 2 語とか 3 語の場合は、この一連の処理を 2 回なり 3 回なり繰り返さなければなりません。

更に 1000 語にもなれば、1000 回記述するわけにも行きませんから、何らかのループ処理が必要に

なります。

1 話が難しくなるので、詳しい説明はしません。 2 説明書に定義されているわけではありません。本書の勝手な設定です。詳しくは 3 章で。 3 IBM 汎用機のアセンブラでは可能です。

変数 A

レジスタ

変数 B

Page 4: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 4

また、

「変数 A の内容と変数 B の内容を加算し、結果を変数 C へ設定する」

ような処理では、

C 言語 c=a+b;

COBOL COMPUTE C = A + B.

または

ADD A B GIVING C.

と記述します。

このような場合でもアセンブラでは、

①汎用レジスタへ変数 A の内容をロードする

②汎用レジスタへ変数 B の内容を加算する

③汎用レジスタの内容を変数 C へストアする

という処理になります。大変面倒です。

図図図図 2222----3333 アセンブラアセンブラアセンブラアセンブラでのでのでのでの加算処理加算処理加算処理加算処理

このように「処理に必須」な汎用レジスタですので、数もひとつだけではなく 8 個用意されています。

また、8 個の汎用レジスタには 0~7 までの番号がついており、「汎用」ということで GR0~GR7 とも記

述します(GR:General Register)。

指標指標指標指標レジスタレジスタレジスタレジスタ

このうちこのうちこのうちこのうち,,,,GR1 GR1 GR1 GR1 ~~~~ GR7 GR7 GR7 GR7 ののののレジスタレジスタレジスタレジスタはははは,,,,指標指標指標指標レジスタレジスタレジスタレジスタ((((IIIIndex ndex ndex ndex RRRRegisteregisteregisteregister))))としてとしてとしてとしてアドレスアドレスアドレスアドレスのののの修飾修飾修飾修飾にもにもにもにも用用用用

いるいるいるいる。。。。

指標レジスタは「指標レジスタ」という特定のレジスタがあるわけではなく、汎用レジスタで代用しま

す。

ただし、GR0 は使用できません(理由は第 4 章で)ので、GR1~GR7 までの 7 個が指標レジスタとして

も使用できることになります。

では、指標レジスタはどのような場合に、どのようにして使用するのでしょうか。

上記「汎用レジスタ」のところで述べましたが、今、

「変数 A から始まる 1000 語の領域を、変数 B から始まる 1000 語の領域へ転送する」場合、

①汎用レジスタへ変数 A の内容を持ってくる(ロードする)

②汎用レジスタの内容を変数 B へ格納する(ストアする)

この処理を 1000 回コーディングするのは現実的ではありません。

このような場合、高級言語では次のようなコーディングになるでしょうか。

変数 A

レジスタ 変数 B

変数 C

Page 5: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 5

C 言語 b[i]=a[i]; これを 1000 回繰り返す(実際は strcpy などの関数を使用するので

しょうけれど)

COBOL MOVE A(I) TO B(I). これを 1000 回繰り返す(実際は集団項目を確保し、1 回の

MOVE 命令で済ますのでしょうけれど)

アセンブラでも同様にインデックスを順に変化させて、1 語ずつ転送します。

このときのインデックス(上記例では、「i」)の役目をするのが指標レジスタになります。

詳細は第 2 部で。

単に「変数 A」としないで、わざわざ「変数 A から始まる・・・」としたのは、次の理由からです。

高級言語では、変数を確保した場合、領域の大きさにかかわらず領域全体が変数名と対応

します。

たとえば、次のようなコーディングでは 1000 バイトの領域が確保されます。

C 言語 char a[1000];

COBOL A PIC X(1000).

アセンブラでは

A DS 1000

とした場合、

「変数 A に 1000 語の領域を割り当てる」のではなく、「1000 語の領域を確保し、その先頭アド

レスに A という名前をつける」という意味になります。

スタッスタッスタッスタックククク

SPSPSPSP((((スタックポインタスタックポインタスタックポインタスタックポインタ,,,,Stack PointerStack PointerStack PointerStack Pointer))))はははは,,,,スタックスタックスタックスタックのののの最上段最上段最上段最上段ののののアドレスアドレスアドレスアドレスをををを保持保持保持保持しているしているしているしている。。。。

まず、「スタック」について説明します。

スタックとは、記憶領域の一種ですが、ここへは PUSH命令でデータを「溜め込む」ことができ、POP命

令で取り出すことができます。

ただし、POP 命令では「PUSH 命令で、最後に溜め込んだデータ」が取り出されます。つまり FILO

(FirstIn LastOut)方式になっています。

今、スタックへ 100 個のデータを溜め込んだとします。このとき、POP 命令で最初に取り出されるのは、

最後に PUSH したデータになるわけです。

箱へレンガを入れることを想像してください。レンガは箱の口と同じ大きさで、何段も積み重ねること

ができます。スタックは、こんなイメージです。

ここへ、レンガを 1 個入れると箱の口からレンガが見えます。

レンガを次々と入れると、前に入れたレンガは後で入れたレンガで隠されるので、箱の口から見えて

いるのは、常に最後に入れた連歌になります。

ここで、レンガを上から取り出すと、最後に入れたレンガが取り出され、更に取り出すと一つ前に入

れたレンガが取り出されます。

最初に入れたレンガは最後にならないと取り出すことができません。

スタックへデータを入れるには、通常 PUSH 命令を使用し、取り出しは POP 命令で行います。

Page 6: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 6

図図図図 2222----4444 PUSHPUSHPUSHPUSH とととと POPPOPPOPPOP

スタックへデータを入れるのは、このほかに CALL命令があります。また RET命令で取り出しが行われ

ます。

この詳細については、命令の説明のところで述べます。

イメージとしてはこのとおりなのですが、スタック機能を実装する場合、次の2つの方法が考えられま

す。

①スタック領域の先頭から、後方(アドレスの増加方向)へ向かって順にスタックしていく方式

②スタック領域の最後から、前方(アドレスの減少方向)へ向かって順にスタックしていく方式

いずれの方式が採用されているかは定義されていません1が、どちらの方式を採るにしても、「現在

どこまでデータをスタックしているか」を覚えておく必要があります(ユーザー責任で覚えるのではな

く、CASLⅡのシステムとして)。

この「どこまでデータが格納されているか」を覚えておくのが「スタックポインタ」です。

プログラムレプログラムレプログラムレプログラムレジスタジスタジスタジスタ

PRPRPRPR((((プログラムレジスタプログラムレジスタプログラムレジスタプログラムレジスタ,,,,Program RegisterProgram RegisterProgram RegisterProgram Register))))はははは,,,,次次次次にににに実行実行実行実行すべきすべきすべきすべき命令語命令語命令語命令語のののの先頭先頭先頭先頭アドレスアドレスアドレスアドレスをををを保持保持保持保持してしてしてして

いるいるいるいる。。。。

説明では「次に実行すべき命令の先頭アドレスを保持している」となっています。

詳しい説明の前に・・・

コンピュータが命令を規則に従って順に処理していく仕組みはどのようなものでしょうか。

通常、プログラム(命令群+データ群)はメモリー上に展開されています(このような方式を「ストアー

ド・プログラム Stored Program 方式」といいます)。

プログラムの開始に先立ち、オペレーティングシステムは、プログラムの最初の命令が格納されてい

るアドレスをプログラムレジスタへ格納します。

その後の命令の実行は次のようになります。

①最初の命令を、プログラムレジスタの示すアドレスから取り出す(1 語)

②命令の長さが 2 語(4 章で詳しく説明します)の場合は、次のアドレスから命令の続きも取り出す

③命令の長さが 1 語のときは 1 を、2 語のときは 2 をプログラムレジスタへ加算する

④命令を実行する

⑤①へ戻る

このようにして、順にプログラムを実行していきます。

(上記①~③をフェッチサイクル Fetch cycle、④⑤をエグゼキュートサイクル Excecute cycle と

1 PUSH 命令、CALL 命令ではスタックポインタの値が 1 だけ減少し、逆に POP 命令、RET 命令では 1 だけ増加すると

定義されていますので、②の方式を採用しているようです。

PUSH

POP

Page 7: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 7

呼びます)。

それでは分岐命令はどうするのでしょうか。

高級言語で言う

C 言語 goto ラベル;

COBOL GO TO ラベル.

という命令です。

分岐命令では、分岐先のアドレスをプログラムレジスタへ格納します。

上記④の「命令を実行する」という動作は、分岐命令では、まさに「分岐先のアドレスをプログラムレ

ジスタへ格納」することになるのです。

プログラムレジスタは、CALL命令や RET命令でも、ちょっと変わった動きになりますが、これは 4章で

説明します。

フラグレジスタフラグレジスタフラグレジスタフラグレジスタ

FRFRFRFR((((フラグレジスタフラグレジスタフラグレジスタフラグレジスタ,,,,Flag RegisterFlag RegisterFlag RegisterFlag Register))))はははは,,,,OFOFOFOF((((Overflow FlagOverflow FlagOverflow FlagOverflow Flag),),),),SFSFSFSF((((Sign FlagSign FlagSign FlagSign Flag),),),),ZFZFZFZF((((Zero FlagZero FlagZero FlagZero Flag))))とととと

呼呼呼呼ぶぶぶぶ 3 3 3 3 個個個個ののののビットビットビットビットからなりからなりからなりからなり,,,,演算命令演算命令演算命令演算命令などのなどのなどのなどの実行実行実行実行によってによってによってによって次次次次のののの値値値値がががが設定設定設定設定されるされるされるされる。。。。これらのこれらのこれらのこれらの値値値値はははは,,,,条件条件条件条件

付付付付きききき分岐命令分岐命令分岐命令分岐命令でででで参照参照参照参照されるされるされるされる。。。。

プログラムを作成するときには、いろいろな判断が必須になります。

大小関係、ある値に等しいか、正負判断などいろいろですが、判断の後で命令を記述し、常に判断

とペアでプログラムを作成します。

たとえば、

「変数 A が 1 なら、変数 B に 1 を加算する」

という場合、

C 言語 if (a==1) b++;

COBOL IF A = 1 ADD 1 TO B.

というようになり、決して「判断のみ」の命令というものはありません。

つまり、

C 言語 if (a==1)

COBOL IF A = 1

だけではプログラムとしては意味の無いものになります(場合によってはコンパイル時にエラーにな

ります)。

ところがアセンブラでは、「判断」とそれに続く「命令」は別々に記述します。

上の命令をアセンブラで記述するには、次のような順序になります。

①変数 A の内容を汎用レジスタへロードする

②汎用レジスタと 1 を比較する(1 が格納されているアドレスの内容(つまり、「1」と比較する)

③比較の結果が保存される

④保存された結果を見て、分岐するかどうかを決定する

となります。

このとき、③で比較結果を保存しますが、この「保存する」場所がフラグレジスタになります。④では、

フラグレジスタの内容を見て分岐を決めることになります。

Page 8: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 8

(アセンブラでは、判断のあとは「分岐」命令しか記述できません。「1 を加算する」というような命令は、

分岐先で記述します。詳細は 5 章で)。

フラグレジスタに値が設定されるのは、比較命令だけではなく、次のような命令でも設定されます。

比較命令(算術比較、論理比較)

ロード命令

算術加算、論理加算、算術減算、論理減算

論理積、論理和、排他的論理和

シフト命令(算術シフト、論理シフト)

このように、多くの(というよりは、ほとんどの)命令でフラグレジスタの内容が変わります。

ところで、判断は必ずしも比較命令のみで行うわけではありません。

上述のように「ロード命令」でもフラグレジスタが設定されるので、ある変数が正、負、ゼロかどうかと

いうような判断をする場合、比較をしなくても判断することができます。

ある変数をレジスタへロードすると、その内容(正/負/ゼロ)によってフラグレジスタには異なる値

が設定されますので、あとは分岐命令を記述すればよいのです。

以下、3 種類のフラグレジスタについて説明します。

OFOFOFOF

算術演算命令算術演算命令算術演算命令算術演算命令のののの場合場合場合場合はははは,,,,演算結果演算結果演算結果演算結果がががが----32768 32768 32768 32768 ~~~~ 32767 32767 32767 32767 にににに収収収収まらなくなったときまらなくなったときまらなくなったときまらなくなったとき 1 1 1 1 になりになりになりになり,,,,それそれそれそれ以以以以

外外外外のときのときのときのとき 0 0 0 0 になるになるになるになる。。。。論理演算命令論理演算命令論理演算命令論理演算命令のののの場合場合場合場合はははは,,,,演算結果演算結果演算結果演算結果がががが 0 0 0 0 ~~~~ 65535 65535 65535 65535 にににに収収収収まらなくなったときまらなくなったときまらなくなったときまらなくなったとき 1 1 1 1 にににに

なりなりなりなり,,,,それそれそれそれ以外以外以外以外のときのときのときのとき 0 0 0 0 になるになるになるになる。。。。

算術演算は(CASLⅡでは)足し算と引き算のみが定義されています。

足し算、または引き算の結果が、-32768~+32767 の間に収まらないときに、OF が 1 に設定され、収まるときに

は 0 に設定されます。

例えば、20000+20000 は 32767 より大きいので、1 が設定されます。20000+12767 はちょうど 32767 となり、0

が設定されます。

ちなみに、-32768~+32767 というのは、レジスタが 16 ビットで、うち 1 ビットは符号で使用しているため、このよ

うな制限になります。

また、論理演算では符号がありませんから、最上位ビットもすべて数値の一部と考えて、0~65535 までとなりま

す。

0 0000 0000 0000 0000

65535 1111 1111 1111 1111

表表表表 2222----1111 符号符号符号符号なしなしなしなし数値数値数値数値のののの下限下限下限下限とととと上限上限上限上限

SF SF SF SF

演算結果演算結果演算結果演算結果のののの符号符号符号符号がががが負負負負((((ビットビットビットビット番号番号番号番号 15 15 15 15 がががが 1111))))のときのときのときのとき 1111,,,,それそれそれそれ以外以外以外以外のときのときのときのとき 0 0 0 0 になるになるになるになる。。。。

ZF ZF ZF ZF

演算結果演算結果演算結果演算結果がががが零零零零((((全部全部全部全部ののののビットビットビットビットがががが 0000))))のときのときのときのとき 1111,,,,それそれそれそれ以外以外以外以外のときのときのときのとき 0 0 0 0 になるになるになるになる。。。。

演算結果、符合については 1 章を参照してください。

Page 9: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 9

論理演算論理演算論理演算論理演算

(6) (6) (6) (6) 論理加算又論理加算又論理加算又論理加算又はははは論理減算論理減算論理減算論理減算はははは,,,,被演算被演算被演算被演算データデータデータデータをををを符号符号符号符号のないのないのないのない数値数値数値数値とみなしてとみなしてとみなしてとみなして,,,,加算又加算又加算又加算又はははは減算減算減算減算するするするする。。。。

これについては、「算術、論理演算命令」のところで、詳しく説明します。

■■■■ 2.2 2.2 2.2 2.2 実効実効実効実効アドレスアドレスアドレスアドレス

命令を学習するに先立ち、実効アドレスについて説明します。

実効実効実効実効アドレスアドレスアドレスアドレス

説明にもあるとおり、実効アドレスとは、「adr で示されるアドレスと指標レジスタの内容を加算し、

65536 で割った余り」をいいます。

指標レジスタは、説明した通りインデックスの代わりとして用いますから、adr に加算するとして、なぜ

65536 で割るのでしょうか。

理由はふたつあります。

理由理由理由理由1111:このハードのメモリーが 65535 番地までしか無いからです。これ以上のアドレスは存在しませ

んから使いようがありません。

理由理由理由理由2222:これはちょっと難しいのですが、このハードは 16 ビットを基本として設計されています。16

ビットで表現できる最大の値(符号を考慮しないとして)が 65535 で、これを越えるとオーバーフロー

して、残り(つまり剰余)が 0~65535 までになるからです。

例えば、3 桁しかないソロバンを考えてみてください。

いま、900 が置かれているとして、これに 200 を加えるとどうなるでしょうか。答えは 1100 ですが、3 桁

しかありませんから、「千」の位はなくなって、残っているのは 100 だけになります。

これと同じように、CASLⅡでも、「16 ビットで表現できる範囲」を超えた場合、超えた部分がなくなって

しまいます。

■■■■ 2.3 2.3 2.3 2.3 命令命令命令命令

説明書によれば、命令は大きく次のように分類1されています。

① ロード、ストア、ロードアドレス命令

② 算術、論理演算命令

③ 比較演算命令

④ シフト演算命令

⑤ 分岐命令

⑥ スタック操作命令

⑦ コール、リターン命令

1 IBM のメインフレームでは、「スタック」がありませんので「スタック操作命令」というのはありません。また、「コール、

リターン命令」は「分岐命令」に分類されます。また、「その他」の「ノーオペレーション命令」も「分岐命令」に分類さ

れます。

Page 10: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 10

⑧ その他

以下、順に説明します。

2.3.12.3.12.3.12.3.1 ロードロードロードロード命令命令命令命令

ロード命令にはふたつの書き方があります。それぞれについて説明します。

LD r1,r2LD r1,r2LD r1,r2LD r1,r2

この命令は、r2 の内容を r1 へコピーするものです。

仮に、汎用レジスタ 3 に 1000 という値が入っていたとします。

LD GR1,GR3

これで、汎用レジスタ 1 にも 1000 という値が設定されます。汎用レジスタ 1 の元の値が何であれ、

1000 に設定されます。

一方、GR2 の値はそのままかわらずに残ります。

レジスタの書き方として、たとえば汎用レジスタ 1 を指定する場合、説明書では

GR1

と書くと定義されています。

IBM メインフレームのアセンブラ言語では単に「1」と書き、他の書き方はエラーになります。

しかし、CASLⅡでは

LD 1,2

と書いた場合、「2」は、「汎用レジスタ 2」を指すのか、それとも「2 番地」を指すのか判別できな

いことになってしまいます。

そこでこれを区別するためには、汎用レジスタは「GR」を付けて書くことになります。

ただし、この場合、変数名として「GR0」から「GR7」は使用できないことになります。アセンブラ言

語で予約語があるというのも首をかしげるところではありますが・・・

また、以降は「汎用レジスタ」という言葉の代わりに「GR」と書くことにします。

この命令は、一体何に使用するのでしょうか。

単に、レジスタの値をコピーする目的もありますが、レジスタの内容が正の値/負の値/ゼロかを判

定する場合にも使用します。

この命令実行後に、r1 の値(つまり r2 の値)によりフラグレジスタが次のように設定されます。

OF SF ZF

r1>0 0 0 0

r1=0 0 0 1

r1<0 0 1 0

表表表表 2222----2222 LDLDLDLD 命令後命令後命令後命令後ののののフラグレジスタフラグレジスタフラグレジスタフラグレジスタのののの値値値値

OF は常にゼロが設定されますので、SF と ZF の値から、r1 が正/負/ゼロのいずれであったかを判

定できます。

Page 11: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 11

ところで、

LD GR1,GR1

という命令を実行するとどのような結果になるのでしょうか。

これは、GR1を GR1へコピーする命令ですから、何も変化は無いように見えます。確かに、汎用レジス

タやメモリーの内容は変化しませんが、フラグレジスタがセットされます。

LD r,adr[,x]LD r,adr[,x]LD r,adr[,x]LD r,adr[,x]

この命令では実効アドレス(adr[,x])の内容が汎用レジスタ r へコピーされます。

LD GR1,1000

この命令では、1000 番地の内容が GR1 へコピーされます。1000 番地の内容は変化しません。

通常プログラムを作るときは、「1000」などの直接数値を書くことはあまりありません。

通常は変数を書くことになります。

たとえば、

LD GR1,KINGAKU

というように書き、アセンブラ(コンパイラ)が「KINGAKU」を 1000 に変換します。詳細は「プログラム

の演習のところで説明します。

GR1GR1GR1GR1 へはへはへはへは、「、「、「、「1000100010001000 番地番地番地番地のののの内容内容内容内容」」」」ががががコピーコピーコピーコピーされるのであってされるのであってされるのであってされるのであって、「、「、「、「1000100010001000」」」」ががががセットセットセットセットされるのではありませんされるのではありませんされるのではありませんされるのではありません。。。。

それでは、インデックス(x)が指定されている場合はどうなるでしょうか。

今、GR2 に 500 が入っているとします。

LD GR1,1000,GR2

この命令では、1000 と GR2 の中身である 500 が加算されて(1000+500=1500)、1500 番地の内容が

GR1 へコピーされます。1500 番地の内容は変化しません。

なお、どちらの場合でもコピーされた値によってフラグレジスタが更新されます。

2.3.22.3.22.3.22.3.2 ストアストアストアストア命令命令命令命令

ストア命令は、ロード命令と反対の動きをします。つまり、汎用レジスタの内容が実効アドレスの番地

へコピーされます。汎用レジスタの内容は変化しません。

ST r,adr[,x]ST r,adr[,x]ST r,adr[,x]ST r,adr[,x]

いま、GR2 に 500 が入っているとします。

ST GR1,1000,GR2

この命令では、GR1 の内容が 1500 番地へコピーされます。

汎用レジスタの内容は、どれも変わりません。

インデックスを使用しない場合は、

ST GR1,1000

Page 12: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 12

のように記述します。

ストア命令では、フラグレジスタも設定されませんので、そのまま残っています。

ところで、ストア命令には、

ST r1,r2

という形式の書き方はありません。

仮に「あった」としたら、

ST GR1,GR2

とでもなって、「GR1 の内容を GR2 へコピーする」という動作になるのでしょうか。

でも、これは、

LD GR2,GR1

とまったく同じ動作1になります。

同じ動作であれば、命令を二つ用意することもないわけです。

2.3.32.3.32.3.32.3.3 ロードアドレスロードアドレスロードアドレスロードアドレス命令命令命令命令

この命令はロード命令と似ていますが、名前の通り「アドレスそのもの」をレジスタへ設定します。

LAD GR1,1000

この命令では、実効アドレスそのものが GR1 に設定されます。つまり、1000 が設定されます。

LD GR1,1000

では、「1000 番地番地番地番地のののの内容内容内容内容」が設定されましたが、LAD 命令では、1000 そのものが設定されるわけで

す。

仮に 1000 番地の内容が 300 だった場合、LD 命令では 300 が設定されます。

図図図図 2222----5555 LADLADLADLAD 命令命令命令命令とととと LDLDLDLD 命令命令命令命令

それでは、インデックスを使用した場合はどうでしょうか。

仮に(例によって)、GR2 に 500 が入っているものとします。

LAD GR1,1000,GR2

この命令では、実効アドレス 1500(1000+GR2 の中身の 500)が GR1 に設定されます。つまり GR1 は

1500 になります。

くどいようですが、「1500 番地の中身」が設定されるのではありません。

1 厳密には、フラグレジスタが設定されない点が、ロード命令とは異なりますが・・・

1000 300 300

1000 番地

LAD 命令 LD 命令

Page 13: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 13

それでは、次の命令はどうなるでしょうか。

LAD GR1,1,GR1

GR1 の内容を x とします。実効アドレス部分は「1,GR1」ですから実効アドレスは、1+x になり、これが

GR1 に設定されます。

元の GR1 の中身・・・x

命令実行後の中身・・・x+1

つまり、GR1 に+1 する命令というわけです。

LAD GR1,5,GR1

と書けば、GR1 に 5 が加算されますし、

LAD GR1,-2,GR1

と書けば、GR1 から 2 が引かれることになります。

なお、ロードアドレス命令ではフラグレジスタは変化しません。

ところで、この命令は汎用レジスタにある数を加えたり引いたりするほかに、何に使うのでしょうか。こ

れは「プログラム演習」の章で説明します。アセンブラ言語の醍醐味が、このロードアドレス命令なの

です。

2.3.42.3.42.3.42.3.4 算術加算命令算術加算命令算術加算命令算術加算命令

何やらいかめしい名前ですが、要するに「足し算」の命令です。

「算術加算」というからには、「算術でない加算」という変な命令もあるのでしょうか。

あります。「論理加算」という命令です(後述します)。

CASLⅡでは、「算術」と「論理」を、「レジスタの一番左のビットを符号としてあつかうか否か」で分けて

います。

符号として扱う命令が、「算術○○」という命令で、扱わないのが「論理○○」という命令になります。

ADDA r1,r2ADDA r1,r2ADDA r1,r2ADDA r1,r2

もうお分かりかと思いますが、この命令では、汎用レジスタ r2 の内容を r1 へ加算し、結果が r1 に入

ります。r2 の内容は変化しません。

今、GR1 に 100、GR2 に 200 が入っていたとすれば、

ADDA GR1,GR2

で、汎用レジスタ 1 には 300 が格納されます。汎用レジスタ 2 は元のままです。

ADDA r,adr[,x]

この記述では、実行アドレスの内容が汎用レジスタ r に加算されます。実効アドレスの内容は変わり

ません。

Page 14: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 14

いま、汎用レジスタ 1 に 100、汎用レジスタ 2 に 200、(メモリーの)1200 番地には、300 が入っていた

とすれば、

ADDA GR1,1000,GR2

adr が 1000、インデックス(汎用レジスタ 2)には 200 が入っていますから、実効アドレスは 1200 にな

りますので、1200 番地の内容である 300 が汎用レジスタ 1 の 100 に加算されて、結果、汎用レジスタ

1 には 400(100+300)が設定されます。

汎用レジスタ 2 に内容も 1200 番地の内容も変化はありません。

算術加算命令では、どちらの書き方でもフラグレジスタが設定されます。

OF SF ZF

r1>0 *1 0 0

r1=0 *1 0 1

r1<0 *1 1 0

*1 計算結果が-32768~+32767 の間に収まらない場合は「1」に、収まれば「0」になる1

表表表表 2222----3333 ADDAADDAADDAADDA 命令後命令後命令後命令後ののののフラグレジスタフラグレジスタフラグレジスタフラグレジスタのののの値値値値

2.3.52.3.52.3.52.3.5 論理加算命令論理加算命令論理加算命令論理加算命令

基本的には算術加算と同じですが、符号を考慮しない点が算術加算と違うところです。符号を考慮

しませんから、負の数値という概念は無く、0~65535 までの範囲の値になります。

書き方、考え方は算術加算と同じです。

フラグレジスタのうち、OF については設定のされ方が算術加算とは少し異なります。「論理」加算です

から、-32768~+32767 までではなく、0~+65535 までの間に収まらないときに OF が設定されます。

2.3.62.3.62.3.62.3.6 算術減算命令算術減算命令算術減算命令算術減算命令

足し算が引き算になるだけで、考え方は算術加算と同じです。

SUBA r1,r2SUBA r1,r2SUBA r1,r2SUBA r1,r2

この書き方は、r1 の内容から r2 の内容を引き算し、結果を r1 に設定します。R2 の内容は変わりま

せん。

SUBA r,adr[,x]

これも算術加算と同じで、r から実効アドレスで示されるアドレスの内容を引き算します。

今、汎用レジスタ 1 に 1000、汎用レジスタ 2 に 300、1300 番地の内容が 600 であるとき、

SUBA GR1,1000,GR2

は、どうなるでしょうか。

実効アドレス 1000+300(インデックスの内容)

実効アドレスの内容(1300 番地の内容) 600

したがって、1000-600=400が、GR1に設定されます。GR2の内容、1300番地の内容は、ともに変化し

1 オーバーフローした場合、加算結果がどうなるかについては規定されていないが、オーバーフローした残りの部

分(加算結果を 32768 で割った余り)が設定されると思われる

Page 15: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 15

ません。

2.3.72.3.72.3.72.3.7 論理減算命令論理減算命令論理減算命令論理減算命令

符号を考慮しない減算命令で、考え方は算術減算と同じです。

2.3.82.3.82.3.82.3.8 論理積論理積論理積論理積、、、、論理和論理和論理和論理和、、、、排他的論理和命令排他的論理和命令排他的論理和命令排他的論理和命令

それぞれ、汎用レジスタと、汎用レジスタまたは実行アドレスの指す番地の内容との間で、ビット毎に

論理積、論理和、排他的論理和をとり、結果を汎用レジスタへセットする命令です。

演算は 1 語 16 ビットすべてのビットについて行われます。

AND r1,r2 r1 と r2 の論理積をとり、結果を r1 へセットする

OR r1,ADR1 r1 と ADR1 番地の内容とで論理和をとり、結果を r1 へセットする

論理積、論理和、排他的論理和の演算は次のように定義されています。

ビット 1 ビット 2 結果 説明

0 0 0 0 1 0

1 0 0 論理積

1 1 1

両方が「1」のときのみ結果が「1」になる

0 0 0

0 1 1

1 0 1 論理和

1 1 1

少なくともどちらか片方が「1」のとき「1」となる

0 0 0

0 1 1

1 0 1 排他的論理和

1 1 0

両方が異なるとき「1」となり、同じ時は「0」となる

表表表表 2222----4444 論理演算論理演算論理演算論理演算のののの結果結果結果結果

【例】

それでは実際の例を見てみましょう。

今、GR1 がビットで「0001 0100 1010 1111」で、GR2 が「1011 0011 1000 0101」だったとします。

AND GR1、GR2

とすると、

GR1 0001 0100 1010 1111

GR2 1011 0011 1000 0101

AND 結果 0001 0000 1000 0101

となりますので、この AND 結果が GR1 に設定されます。GR2 の内容は変化しません。

フラグレジスタは3つとも「0」が設定されます。

ところで、これらの命令はどんなときに使用するのでしょうか。

加算命令や減算命令は使い道がわかるのですが、これらの命令はちょっと(使い道の)想像がつき

ませんね。

ということで、例をあげてみます。

Page 16: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 16

ANDANDANDAND 命令命令命令命令

よく使用するのは、「ある特定のビットが、0 か 1 かを判断する」場合です。

例えば、汎用レジスタに「0001 0000 0000 0000」をセットしておき1、これをメモリーとの間で論理積演

算します。

結果が、全ビットゼロになれば(つまり、フラグレジスタ ZF がゼロであれば)「メモリーの左から 4 ビット

目は、もとは 0だった」ということになりますし、ZFがゼロでなければ、「メモリーの左から 4ビット目は、

もとは 1 だった」ということになります。

OROROROR 命令命令命令命令

COMETⅡでは(どのコンピュータもそうですが)文字に 16 進コードが割り振られており、これを「文字

コード」と呼んでいます。

COMETⅡでは1バイト文字2のみ定義されており、このうち数字の「0」~「9」は、それぞれ X’30’~

X’39’に割り振られています。

いま、汎用レジスタに 2 進数の数値(ただし、0~9)があったとき、これを文字に変換するにはどうす

れば良いでしょうか。

COMETⅡでは、「文字」は 1 語に 1 文字で格納され、上位 8 ビット(1 語の左半分)は 0 になると定義さ

れていますから、

X’0000’→X’0030’ X’0001’→X’0031’

・・・ X’0009’→X’0039’

に変換するわけです。

このような場合、いちばん簡単なのは「X’0030’で論理和をとる」という方法です。

たとえば「5(X’0005’)」と X’0030’の論理和は X’0035’になりますので、文字に変換されたこ

とになります。

逆に文字から数値への変換は X’000F’で論理積をとればよいことになります(確認してみてくださ

い)。

XORXORXORXOR 命令命令命令命令

これは難物です。

あまり、良い使用例が思い浮かびません。

あまり役立つとは思えませんが、次のような例はどうでしょうか。

今、

GR1 0001 0101 1100 1110

GR2 1101 0010 1010 0000

が格納されていたとします。

これに次の演算を行います。

① XOR GR1,GR2 ② XOR GR2,GR1 ③ XOR GR1,GR2

1 LD GR1,=#1000 または、LAD GR1,#1000 でセットできる 2 1バイト=8ビットなので、最大 256 種類しか定義できない。漢字コードなどはこれでは不足なので、16ビットが割り

振られており、これを 2 バイトコードという。

Page 17: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 17

順にやってみましょう。

① は、

GR1 0001 0101 1100 1110 GR2 1101 0010 1010 0000

結果 GR1 1100 0111 0110 1110

② は

GR2 1101 0010 1010 0000 GR1 1100 0111 0110 1110

結果 GR2 0001 0101 1100 1110

③ は

GR1 1100 0111 0110 1110 GR2 0001 0101 1100 1110

結果 GR1 1101 0010 1010 0001

さて、なにか気づきましたでしょうか。

そうです、GR1 と GR2 の内容が入れ替わっていますね(単にそれだけですが)。

2.3.92.3.92.3.92.3.9 比較演算命令比較演算命令比較演算命令比較演算命令

比較演算命令は、値の大小を比較し、結果をフラグレジスタへ設定する命令です。通常この命令の

後はジャンプ命令となります。

比較には、算術比較と論理比較があります。

算術比較は比較する値を符号付き数値(最左ビットを符号として扱う)として比較しますから、比較す

る数値の範囲は、-32768~+32767 の間となります。

論理比較では最左ビットを符号としては見ないで、数値の一部として判断します。従って比較できる

範囲は、0~65535 までの間となります。

次の表は数値 1 と数値 2 を、それぞれ算術比較と論理比較でどのような比較結果になるかをまとめ

たものです(値はいずれも 16 進表示です)。

①数値 1 0001 8000 FFFF 8000

②数値 2 0000 7FFF 0000 FFFF

算術比較 ①>② ①<② ①<② ①>②

論理比較 ①>② ①>② ①>② ①<②

表表表表 2222----5555 論理比較論理比較論理比較論理比較とととと算術比較算術比較算術比較算術比較のののの結果結果結果結果

比較は、汎用レジスタ同士、または汎用レジスタと実効アドレスの内容とで行われます。

前述しましたように比較命令は、「比較して、フラグレジスタに結果を設定する」命令です。比較の後

には、(その結果次第で)ジャンプしたり、何らかの演算、更に比較などを行いますが、CASLⅡでは

ジャンプ命令しか記述できません(記述はできますが、フラグレジスタの値によって何かを行うという

命令は、ジャンプ命令しかありません)。

比較命令の後に、「フラグレジスタの内容を変化させない」命令、例えばストア命令やロードアドレス

命令などをはさんで、その後にジャンプ命令を書いてもかまいませんが、バグの元になりますので避

けるほうが賢明です。

今、次のような処理をすることを考えてみます。

① GR1 の内容を変数 A へ格納する

② GR1 と GR2 を比較し、GR1>GR2 であれば NEXT へジャンプする

Page 18: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 18

通常は、次のように記述します。

ST GR1,A CPA GR1,GR2 JPL NEXT

それでは、次のような書き方はどうでしょうか。

CPA GR1,GR2 ST GR1,A JPL NEXT

これでもプログラムは同じように動作しますが、少し不自然です。下の例では、「JPL 命令は、どの命

令の結果を見るのだろう」という疑問が湧きます。ST 命令ではフラグレジスタは変化しませんので、

CPA命令の結果を見ていることは明白ですが、「もしかしたら ST命令でもフラグレジスタが変化するの

だろうか」と一瞬でも考えてしまいます。

2.3.102.3.102.3.102.3.10 シフトシフトシフトシフト命令命令命令命令

シフト命令は、汎用レジスタの 16 ビットを左または右へ指定されたビット数だけ移動させる命令で

す。

汎用レジスタは 16 ビットしかありませんので、17 ビット以上のシフトは意味がありません。

シフト命令も加算・減算命令と同様に「算術シフト」と「論理シフト」があり、算術シフトは符号を考慮し

た命令で、論理シフトは考慮しない命令です。

2.3.112.3.112.3.112.3.11 算術算術算術算術シフトシフトシフトシフト命令命令命令命令

左シフトと右シフトがあります。

左左左左シフトシフトシフトシフト((((算術算術算術算術))))

次の図のように、ビットを移動します。

次の例は、左へ 2 ビット分算術シフトさせた例です。

ビット位置 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

シフト前 0 1 1 0 0 1 1 0 1 0 0 0 1 1 1 0

・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・ ・

シフト後 1 0 0 1 1 0 1 0 0 0 1 1 1 0

図図図図 2222----6666 算術左算術左算術左算術左シフトシフトシフトシフト((((誤誤誤誤))))

それでは、シフトによって「こぼれ落ちる」ビット(上図の黄色の部分)はどうなるのでしょうか。これは

「無くなって」しまいます。

また、シフトによって発生した「隙間」のビット(図の水色の部分)には何が入るのでしょうか。ここには

すべて「0」が格納されます。

それではシフトはどのような場合に使用されるのでしょうか。

一番分かりやすいのが「乗算」と「除算」です。

左へ 1 ビットシフトするということは、「2 倍する」ということになり、左へ n ビットシフトするということは、

「2n」倍するということになります。

逆に右へシフトするということは除算になります。右へnビットシフトするということは、「2n」で割るという

ことになります。

Page 19: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 19

このように乗算や除算に使用できますが、残念ながら「2n」倍する場合や、「2n」で割る場合にしか使

用できません。

ここで質問です。

「負」の数値は最左ビット(15 ビット目)が「1」だったはず。上の例だと、負の数値の場合、左シフトを

行うと状況によって正の数になってしまうことがあります。右シフトでは(隙間に 0が詰まりますから)必

ず正の数になってしまいます。

これはおかしいですね。

実は、上図が間違っているのです。正しくは次のようになります。

ビット位置 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

シフト前 0 1 1 0 0 1 1 0 1 0 0 0 1 1 1 0

・ ・ ・ ・ ・ ・ ・ ・ ・ ・

シフト後 0 0 0 1 1 0 1 0 0 0 1 1 1 0

図図図図 2222----7777 算術左算術左算術左算術左シフトシフトシフトシフト((((正正正正))))

シフトは 0~14ビット目の 15ビットで行われ、最左(15ビット目)は常に 15ビット目へコピーされます。

従って「こぼれ落ちる」のは 13 ビット目と 14 ビット目になります。

右右右右シフトシフトシフトシフト((((算術算術算術算術))))

では、右へ算術シフトする場合はどうなるのでしょうか。

右へ 3 ビットシフトする場合は、次のようになります。

ビット位置 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

シフト前 1 1 1 0 0 1 1 0 1 0 0 0 1 1 1 0

・ ・

・ ・ ・ ・ ・ ・ ・

シフト後 1 1 1 1 1 1 0 0 1 1 0 1 0 0 0 1

図図図図 2222----8888 算術右算術右算術右算術右シフトシフトシフトシフト

この場合、

・ 右の 3 ビット(図の黄色部分)は、「こぼれ落ちて」なくなります。

・ 符号(最左ビット)は左シフトと同様に、符号がコピーされます。

・ 右シフトによってできた「隙間」(図の緑部分)にも符号がコピーされます。

なぜ、このような面倒なことをするのでしょうか。

実際に確認してみましょう。

今、話を単純にするために、4 ビットの符号付き数値(第 1 章で説明した)で考えてみましょう。

符号付きですから、最左ビットは符号ビットになります。

「1 ビット右シフトは 2 で割ることと同じ」と説明しましたが、これを確かめてみます。

まず、5 を 2 で割ってみましょう。

5 は 0101 ですから、右へ 1 ビットシフトすると 0010 になります。これは「2」ですね(余りは無視)。

Page 20: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 20

では、-5 を 2 で割ってみましょう。

-5 はビットでは 1011 になりますから、

1 0 1 1

1 1 0 1

1101 となります。これは-31ですから、確かにこのシフト方法で良い2ことがわかります。

余談ですが、負の数値を正の数値で割ったときの答え(商)と余り(剰余)はどうなるのでしょ

うか。

7 を 2 で割ると、商=3、剰余=1 となりますが、これは問題の無いところです。

では、-7 を 2 で割るとどうなるのでしょうか。

商=-3、剰余=-1 でしょうか。

「余りが負の数になるのはなんとなくヘン」という気がします。

であれば、商=-4、剰余=1 でしょうか。

もし剰余として負の数値を認めるのであれば、7 を 2で割る場合も、商=4、剰余=-1としてもよ

さそうです。

ちなみにマイクロソフトの Excel で剰余を求めたところ、-7 を 2 で割った剰余は 1 となりまし

た。ということは商は-4 ということですね。

Excel で単純に-7/2 としますと、答えが-3.5 となり、少数以下が計算されてしまいます。

QUOTIENT という関数があるようですが、これは商の小数部を切り捨てるという関数ですので、

ちょっと意味が違ってきます。

しかし、そういえば「切り捨て」という動作も考えてみると、「その値を超えない最大の整数に

する」のでしょうか、それとも「ゼロに近い整数にする」のでしょうか。

3.5 を切り捨てますと 3 になります。これは問題ありません。

では、-3.5 を切り捨てるとどうなるのでしょうか。

答えは-3 でしょうか。でも、「越えない最大の整数」という定義をとれば、-4 になります。

浅学の筆者にはよく分かりませんが。

2.3.122.3.122.3.122.3.12 論理論理論理論理シフトシフトシフトシフト命令命令命令命令

算術シフト命令の説明で、「実は、上図が間違っているのです。」と書きましたが、この間違ったシフト

方法が論理シフトです。

「間違った」というと語弊がありますが、つまり「符号を意識しない」シフトが論理シフトというわけです。

左左左左シフトシフトシフトシフト

最左ビットを特別なビットとみないで、シフトするビット数だけ左へ移動します。「こぼれたビット」はな

くなりますし、右側の「空いた」ところには無条件に「0」がセットされます。

右右右右シフトシフトシフトシフト

左シフトと同様に右へシフトされます。左の「空いた」部分には、算術シフトでは符号ビットがコピーさ

れましたが、単に「0」がセットされます。

1 1101 の「2 の補数」は 0011 で 3 になります。つまり、-5 を 2 で割ると商=-3、剰余=1 ということです。 2 というよりも、そうなるようにシフト命令を設計してあるというほうが正確でしょう。

Page 21: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 21

右の「こぼれた」ビットはなくなります。

論理論理論理論理シフトシフトシフトシフトのののの使使使使いいいい道道道道

論理シフト命令は、ある特定のビットが「0」か「1」かを判定する際によく使用されます。

例えば、

変数 A の左から 3 ビット目が「0」か「1」かを判断する

という場合、

LD GR1,A ;① SLL GR1,2 ;② JMI BITON ;③

①の命令で変数 A を GR1 へロードします。

②の命令で左へ 2 ビットシフトしますから、最初の(つまり変数 A の)左から数えて 3 ビット目が GR1の

最左ビットのところへ位置します。

ビット位置 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

シフト前 1 1 1 0 0 1 1 0 1 0 0 0 1 1 1 0

シフト後 1 0 0 1 1 0 1 0 0 0 1 1 1 0

図図図図 2222----9999 ビットビットビットビットのののの判定判定判定判定

このビットが「1」であれば、(負の数値なので)フラグレジスタ SF が「1」に設定されますから、ジャンプ

命令で判断をすることができます。

上記の③では、負の数値なら(ビットが ONなら)BITONというところへジャンプする(次の命令は BITON

から)ことになります。

また、上記②で

SLL GR1,3

とすれば、0 か1かを判断するビットがなくなってしまいますが、フラグレジスタ OF には「レジスタから

最後に送り出されたビットの値が設定される」と定義されていますので、③の命令を

JOV BITON

としても良いことになります。

つまり、上記①~③の命令は、次のように書いても同じということになります。

LD GR1,A ;① SLL GR1,3 ;② JOV BITON ;③

これは右シフトの場合でも同じです。

2.3.132.3.132.3.132.3.13 シフトシフトシフトシフト命令命令命令命令のののの注意点注意点注意点注意点

シフト命令の「シフトするビット数」は実効アドレスで示されたビット数だけシフトされますが、これは

「実効アドレスで示されたアドレスの内容分シフトする」ということではありませんありませんありませんありません。

例を示しましょう。

Page 22: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 22

今、変数 A が 100 番地にあり、その内容が 3 であったとします。

SLL GR1,A

とした場合、変数 A の内容が 3 だからといって、3 ビットシフトされるのではありません。あくまでも 100

ビットシフトされることになります(変数 A が 100 番地なので)。

100 ビット左へ論理シフトすれば、GR1 はゼロになってしまいますが。

このようなわけですから、シフト命令のディスプレースメント1に変数(リロケータブルターム)を指定す

ることは、まず考えられず、ほとんどの場合数値そのもの(アブソリュートターム)を指定します。

これは、変数のアドレスが実行時に何番地になるかは予測できないためです(OSがプログラムのロー

ド時に決定します)。

ただし、インデックスレジスタは使用することがあります。

シフト数が実行時まで決定できないような場合に、

SLL GR1,0,GR2

とすれば、実効アドレスは

0+GR2 の内容

になりますから、結果として GR2 の内容分だけシフトされることになります。

2.3.142.3.142.3.142.3.14 分岐命令分岐命令分岐命令分岐命令

フラグレジスタの内容により分岐する命令です。

次の条件が成立する(真)ときジャンプし、条件にあてはまらない(偽)ときはジャンプせず次の命令

へ移ります。

ジャンプする条件 ジャンプ命令

OF SF ZF

JPL 0 0

JMI 1

JNZ 0

JZE 1

JOV 1

JUMP 無条件にジャンプ

表表表表 2222----6666 フラグレジスタフラグレジスタフラグレジスタフラグレジスタのののの値値値値とととと分岐条件分岐条件分岐条件分岐条件

空白部分は「参照しない」ということです。

従って、たとえば JPL 命令は SF と ZF が 0 のときジャンプし、これ以外の場合はジャンプしないという

ことになります。

この表を見るときは注意が必要です。

1 ディスプレースメント、リロケータブルタームについては、4 章を参照してください。

Page 23: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 23

例えば、OF=1、SF=0、ZF=0 だった場合、各命令は次のようになります。

JPL SF=0、ZF=0 なのでジャンプする

JMI SF=0 なので、ジャンプしない

JNZ ZF=0 なのでジャンプする

JZE ZF=0 なのでジャンプしない

JOV OF=1 なのでジャンプする

JUMP ジャンプする

表表表表 2222----7777 ジャンプジャンプジャンプジャンプ命令命令命令命令のののの意味意味意味意味

分岐命令のオペランドには、インデックスを指定することができます。これは次のような使用法があり

ます。

JUMP TBL1,GR2 ;① ・・・

TBL1 JUMP A1 ;② JUMP A2 ;③ JUMP A3 ;④

この①の JUMP 命令のオペランドは、もし GR2 の指定が無く、

JUMP TBL1

だけであれば、単に TBL1 へジャンプします(その後 A1 へジャンプすることになりますが)。

今、GR2 に 2 が格納されていた場合はどうなるでしょうか。

仮に、TBL1 が 100 番地にあったとしますと、①の命令の実行アドレスは 102(100+2)になりますから、

102 番地へジャンプします。102 番地はちょうど③の命令のところですから、

JUMP A2 ;③

が実行されて A2 へジャンプすることになります。

これは COBOL の

GO TO A1 A2 ・・・ DEPENDING ON XX

に似ています。

似てはいますが、少し違います。①の命令は GR2 が偶数のときにしかうまく行きません。②や③の

JUMP 命令は 2 語の命令1になっているからです。

それでは GR2 が偶数のみでなく奇数の値もとる場合(これが普通ですが)はどうすれば良いでしょう

か。

このような場合は、①のめ異例の前に次のような命令をいれて、GR2 を 2 倍してやればよい訳です。

SLL GR2,1

他にも、もっと「アセンブラチック」な方法がありますが、それは第 5 章で。

1 2 語と定義されているわけではなく、本書の勝手な設定。詳しくは 4 章参照。

Page 24: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 24

2.3.152.3.152.3.152.3.15 スタックスタックスタックスタック操作命令操作命令操作命令操作命令

PUSHPUSHPUSHPUSH 命令命令命令命令

PUSH 命令はスタックにデータ(実効アドレス)を 1 件追加する命令です。たとえば、

PUSH KINGAKU

とすれば、KINGAKU のアドレス(KINGAKU の内容ではありません)がスタックに追加されます。

また、例えば GR1 が 3 であるとき、

PUSH KINGAKU,GR1

とすれば、KINGAKU のアドレス(KINGAKU に割り当てられているアドレス)+3 がスタックに追加されま

す。

スタックについてはハードウェアの仕様のところで説明しましたが、この命令はいったいどのようなと

きに使用するのでしょうか。

CALL 命令でも使用されますが、これについては CALL 命令のところで説明します。

まず、思いつく使い方としては、サブルーチンにパラメータのアドレスを渡す領域が考えられますが、

これは RET 命令との関連でうまく行きません(これについても CALL 命令で説明します)。

では、以下で PUSH 命令と POP 命令の両方を説明しましょう。

しかし、その前に POP 命令です。

POPPOPPOPPOP 命令命令命令命令

POP 命令はスタックから 1 個取り出す命令です。

PUSH/POPPUSH/POPPUSH/POPPUSH/POP 命令命令命令命令

CALL 命令は主に「外部プログラム」を呼び出すための命令です。

外部プログラムとは、「別にアセンブルしたプログラム」と考えて良いでしょう。

PUSH 命令と POP 命令、外部プログラムではないプログラム(内部ルーチン)を呼ぶ場合に便利なよう

です。

この機能は、C 言語では定義されていません(もともと内部ルーチン=関数の呼び出しばかりで出来

ている言語ですが)が、COBOL では PERFORM 命令として定義されています。

次のような例を考えてみましょう。

今、「テストの平均点を求める」ことを考えてみます。

平均点は、国語と算数の 2 教科について求めるとします。

平均点を求めるルーチンを「HEIKIN」とします。

Page 25: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 25

・・・ (国語の全員分の点数読込)

PUSH NEXT1 ;① JUMP HEIKIN ;② NEXT1 ・・・

・・・ (算数の全員分の点数読込) PUSH NEXT2 ;③ JUMP HEIKIN ;④ NEXT2 ・・・

・・・ HEIKIN ・・・

・・・ POP GR1 ;⑤ JUMP 0,GR1 ;⑥

・・・

まず①では、内部ルーチン「HEIKIN」を呼んだあとで、HEIKIN からの戻り先として「NEXT1」のアドレス

を PUSH 命令でスタックへ保存しています。

そして②で「HEIKIN」へジャンプします。

HEIKINでは、処理を終えた後、⑤の POP命令でデータを 1個取り出しますが、これは①で PUSHした

データになりますから、NEXT1 のアドレスを取り出すことになります。

次⑥のジャンプ命令で、NEXT1 へジャンプします(つまり、②の次の命令へ戻ってきたことになりま

す)。

なお、この⑥の使い方は分岐命令のところで説明しました。

さらに、③と④でも同様なことをしていますが、この場合では戻り先が NEXT2 になっていますので、⑤

と⑥で、今度は NEXT2 へ戻ってきます。

NEXT1 のアドレス

最初のスタックの状態

⑤で、戻り先「NEXT1」をスタックか

ら取り出した状態

NEXT1 のアドレス

NEXT1 のアドレス

①で、戻り先「NEXT1」をスタックへ

PUSH した状態

Page 26: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 26

しかし、こんな面倒なことをしないで、単に戻り先アドレスを覚えておくようにしてはどうでしょうか。

つまり、上のプログラムを次のように変更します。

・・・ (国語の全員分の点数読込) LAD GR1,NEXT1 ;① ST GR1,MODORI JUMP HEIKIN ;② NEXT1 ・・・

・・・ (算数の全員分の点数読込) LAD GR1,NEXT2 ;③ ST GR1,MODORI JUMP HEIKIN ;④ NEXT2 ・・・

・・・ HEIKIN ・・・

・・・ LD GR1,MODORI ;⑤ JUMP 0,GR1 ;⑥

・・・ MODORI DS 1 ;⑦

・・・

このプログラムでは、①でPUSH命令の替わりに戻りアドレスを⑦の「MODORI」へ格納しています。③で

も同様です。

戻る場合は、戻り先アドレスを POP 命令で取得するのではなく、MODORI に保存しておいたアドレスへ

戻っています。

これでも立派に動作しますが、ひとつ問題があります。

いま、HEIKIN からさらに GOUKEI という内部ルーチンを呼ぶとしたらどうなるでしょうか。

・・・ (国語の全員分の点数読込) LAD GR1,NEXT1 ;① ST GR1,MODORI JUMP HEIKIN ;② NEXT1 ・・・

・・・ (算数の全員分の点数読込) LAD GR1,NEXT2 ;③ ST GR1,MODORI JUMP HEIKIN ;④ NEXT2 ・・・

・・・ HEIKIN ・・・

・・・ LAD GR1,HEI1 ;⑤ ST GR1,MODORI ;⑥ JUMP GOUKEI ;⑦ HEI1 ・・・

・・・ LD GR1,MODORI ;⑧ JUMP 0,GR1 ;⑨

・・・

Page 27: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 27

GOUKEI ・・・ ・・・

LD GR1,MODORI ;⑩ JUMP 0,GR1 ;⑪

・・・ MODORI DS 1

内部ルーチン HEIKINでは GOUKEIを呼ぶために、⑤と⑥で戻りアドレスを MODORIに保存しています。

そして⑦で GOUKEI へジャンプします。

GOUKEI では、⑩で戻りアドレスを MODORI から取得し、⑪で戻ります(つまり、HEI1 へ戻ってきます)。

HEIKIN は更にメインへ戻ろうとして、⑧を実行しますが、このとき MODORI には⑥で格納されたアドレ

ス、つまり HEI1 のアドレスが格納されています。

したがって、⑨のジャンプ命令では、また HEI1 へ戻ってしまいます。

つまり、⑧→⑨→⑩→⑪を繰り返すことになり、いつまでたっても終了しません(永久ループ)。

これを防ぐためにはどうすれば良いでしょうか。

MODORIを2つ用意し、そのうち1つを「HEIKINから戻るため」に、残りを「GOUKEIから戻るため」に使用

するという考えではどうでしょうか。

これは良い考えのように思えますが、それでは GOUKEIから更に呼び出す必要が出た場合どうなるで

しょうか。

またひとつ用意しなければなりません。

これではキリが無いですね。

そこで次のようなことを考えます。

・戻り先アドレスを格納する領域をたくさん用意し、その先頭に RTNADR という名前をつける

・RTNADR のどこへ格納したかを覚えておくために、変数 RTNPOS を用意し、初期値をゼロにしておく

・戻り先を格納するときは、RTNADR の RTNPOS 番目へ格納し、RTNPOS に+1 しておく

・戻るときは、RTNPOS から 1 を引き、RTNADR の RTNPOS 番目の内容を取り出して、そこへ戻る

これだとうまく行きそうですが、なんだか面倒ですね。

・・・そこで、これを「仕組み」として実装したのが PUSH/POP 命令なのです。

2.3.162.3.162.3.162.3.16 コールコールコールコール、、、、リターンリターンリターンリターン命令命令命令命令

CALLCALLCALLCALL 命令命令命令命令

CALL 命令はサブルーチンを呼び出す命令です。

これについては、6 章で詳しく説明しますが、次の動作を行います。

① CALL 命令の次のアドレスをスタックへ PUSH し、サブルーチンの先頭へ分岐する。

② RET 命令では(CALL 命令でスタックされたアドレスを)スタックから取り出し、その取り出したアド

レスへ分岐します。

RETRETRETRET 命令命令命令命令

CASLⅡの説明では、プログラムの動作を終了する1命令として、この RET命令を使用するとされていま

す。

RET 命令は、サブルーチンから戻る場合に使用する目的で使用される命令です。

少し話が難しくなりますが、

1 END 命令がありますが、これはプログラム全体の終わりを示すもので、プログラムの実行を終了するものではあり

ません。

Page 28: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 28

プログラムには、「メインプログラム(メインルーチン)」と「サブプログラム(サブルーチン)」がありま

す。

一般にサブルーチンはメインプログラムから呼ばれて動作するもので、サブルーチン自体が独自で

実行されることはありません。

しかし、コンピュータ全体を考えてみますと、一番「大元」で動いているのは OS(オペレーティング・シ

ステム)です。

従って、メインプログラムといえども OS から見れば、ある種のサブルーチンの位置付けになります。

というわけで、RET 命令を「プログラム実行の終了」として使用するとされているわけです。

OS から呼び出されるとき、OS は(OS への)戻り先をスタックへ格納してから呼び出します。

2.3.172.3.172.3.172.3.17 そのそのそのその他他他他のののの命令命令命令命令

SVCSVCSVCSVC 命令命令命令命令

日本語では、「スーパーバイザーコール」命令とあり、説明には「実効アドレスを引数として割出しを

行う」とあります。

「スーパーバイザー」、「引数」、「割出し」と、難しそうな言葉が出てきました。

順に説明します。

スーパーバイザースーパーバイザースーパーバイザースーパーバイザー

コンピュータに処理を行わせるために、プログラムを作成し、それを実行させますが、このプログラム

の実行は OS(オペレーティング・システム)が管理しています。

つまり、ユーザーの作成したプログラムは、すべて OS の管理下にあるわけで、このようなプログラムを

「プロブレム・プログラム(problem program)」といいます。

我々が作成するプログラムは、ほとんどがプロブレム・プログラム(面倒なので、以下「PP」と書きます)

ですし、コンパイラやアセンブラなど通常はメーカーから提供されるプログラムも、やはり PP です。

ところで、コンピュータは通常 OS 制御の下で PP が動いているわけですから、(OS もプログラムですか

ら)複数のプログラムが同時に動いている1ことになります。

いま、PP にバグがあって OS のデータ部分を書き換えてしまうとどうなるでしょうか。

OS が正しく動作しなくなってしまいます。

OS はコンピュータの「よりどころ」ですから、OS が動かなくなればコンピュータ自身が止まったり暴走し

たりすることになります。

このような事態を防ぐため、通常は PP から OS のデータを参照したり書き換えたりすることはできない

ような仕組みになっています。

無理に参照したり書き換えたりすると、「アドレス例外」とか「プロテクト例外」で PP が止まる仕組みに

なっています。

とはいうものの、PP から OS のデータを参照したり書き換えたりすることが必要になる場合があります。

このようなときは、PP から直接 OS を参照したり書き換えたりしないで、OS 側で用意されたルーチンに

処理を依頼することにしています。

いってみれば、「素人がするのではなく、プロに依頼する」のです。

この、OS 側で用意された「ルーチン」のことを「スーパーバイザー」といいます。

1 実際は「同時」に動いているわけではなく、非常に短時間で切り替わっているので、同時に感じられるだけです。

なお、PP が動いているときを「PP モード」、OS が動いているときを「スーパーバイザーモード」といいます。

Page 29: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 29

通常、スーパーバイザーはたくさんの種類があり、たとえば、「タイマーをセットする」とか、「排他制御

をする」とかの仕事の種類により、番号が付けられています。

そして、このようにスーパーバイザーを呼び出す(仕事を依頼する)ことを「スーパーバイザー・コー

ル」と言っているのです。

また、「スーパーバイザーに仕事を頼んで、スーパーバイザーがそれを実行する」ことを「割出し」と

いいます。

CASLⅡではスーパーバイザー・コール(SVC 命令)では、パラメータに実行アドレスを指定することに

なっており、この「実効アドレス」は「引数」であるとしています。

引数(パラメータ)というのは、スーパーバイザーの種類、依頼する仕事に必要な変数などを指しま

すが、具体的には定義されていません。

スーパーバイザー自体についても何も書かれていませんので、おそらくこの命令を使用することは

無いと思われます。

「「「「割出割出割出割出しししし」」」」とととと「「「「割込割込割込割込みみみみ」」」」

この説明書では、「割出し」という言葉が使われていますが、「割込み」という言葉を遣う場合も

多いようです。どちらも「interrupt」の訳語と思われます。

「出し」と「込み」は意味がまったく反対ですが、微妙に似たところもあります。

たとえば、PC から MO などにデータを書く場合、何と言うでしょうか。

通常は「書き込む」といいますが、PC から見て「書き出す」ということもあります。

似たような言葉で、時間を示す「前」という言葉があります。

通常、「前」といえば過去のことですが、なんとなく「未来」についても使いそうではないですか。

NOPNOPNOPNOP 命令命令命令命令

No OPeration 命令で、名前のとおり「何もしない」命令です。「ノップ」と発音します。

通常はジャンプ命令の特別な形(次の命令へジャンプする)として定義される場合が多いのですが、

CASLⅡでは特別に NOP を定義しているようです。

この命令はいったい何に使用するのでしょうか。

いくつか例をあげてみます。

NOPNOPNOPNOP 命令命令命令命令ににににラベルラベルラベルラベルをつけるをつけるをつけるをつける

3章で説明しますが、CASLⅡではひとつの命令は 1行に書かなければならず、複数の行に分けて書

くことができません。

たとえば、次のように書きます。

LABEL1 ADDA GR1,TEATE ST GR1,GOUKEI

1 行目は次のように書くとエラーになります。

LABEL1 ;ラベルのみはエラーです ADDA GR1,TEATE

Page 30: 2222章章 章 システム COMET ... - genshuan.web.fc2.comgenshuan.web.fc2.com/CASL/CASL_2.pdf · - - 4 また、 「変数aの内容と変数bの内容を加算し、結果を変数cへ設定する」

- - 30

ここで、最初の命令の前に命令をひとつ挿入する必要が生じたとします。

たとえば、次のように修正する場合です。

LABEL1 LD GR1,GOUKEI ADDA GR1,TEATE ST GR1,GOUKEI

この場合 2 行修正しなければなりません。

では、次のようにコーディングしてあればどうでしょうか。

LABEL1 NOP ADDA GR1,TEATE

ST GR1,GOUKEI

1 行追加する場合は、

LABEL1 NOP LD GR1,GOUKEI ADDA GR1,TEATE

ST GR1,GOUKEI

とすればよく、修正は 1 行ですみます。

ラベルのついた命令を削除する場合も同じですね。

IBM のアセンブラでは「EQU」という命令があります。

この命令(実行命令ではありませんが)は、いろいろ使い方がありますが、ラベルのみの行をコーディ

ングする手段としても使用されます。

たとえば、

LABEL1 EQU * AH 1,TEATE

これに 1 行追加するのは簡単ですね。

LABEL1 EQU * LH 1,GOUKEI

AH 1,TEATE

CASLⅡにはこのような命令が無いので、NOP で代用しようというわけです。

命令命令命令命令をををを変更変更変更変更するするするする

5 章で説明しますが、実行時に命令を作り出すために使用します。

実行時まで処理が決まらない場合、とりあえず「NOP」として、命令の領域を確保しておき、実行時に

命令を作り出して、これを実行するのです。

実行時に命令を作る・・・アセンブラならでは1ですね。

1 REXX などでも可能です。