3 章 アセンブラ言語 CASLⅡ の仕様 ここでは アセンブラ言語の説明をします ちょっと待て 第 2 章の話は アセンブラ言語の話ではなかったのか と思われた人はいませんでしょうか 一般に プログラム という場合 その構成要素は次の 3 つに分かれます 1 動作のための命令加算 減算 比較などの命令 2 領域確保や定数定義など 動作しない部分 3 プログラム名の定義などこのうち 1が第 3 章で説明した部分にあたります この章では2と3について説明します - 1 -
3.1 言語の仕様 コーディングの仕方についての説明です (1) CASLⅡは COMETⅡのためのアセンブラ言語である これは あたりまえ の話のようですが COBOL や C Java といった いわゆる 高級言語 は 特に どのコンピュータのため ということが決まっていません それぞれのコンピュータ用のコンパイラがありますので 多くのコンピュータで使用できます ただし アセンブラ言語はコンピュータに対応したアセンブラ言語があり 一般的に他のコンピュータでは使用できない 1 特有の 言語ですので このような表現になっています (2) プログラムは 命令行および注釈行からなる コーディングにあたっては 命令の行と注釈 ( コメント ) の行があるということです これについては (4) でも述べます (3) 1 命令は 1 命令行で記述し 次の行へ継続できない 高級言語では あまり 行 という概念がありません 1 行に複数の命令を書いたり ひとつの命令を複数行にわたって書いたりできます CASLⅡでは このようなことは認められておらず 1 行にひとつの命令しか書けないということです 多くの他のアセンブラ言語も このような仕様になっているようです (4) 命令行および注釈行は 次に示す記述の形式で 行の 1 文字目から記述する ここでは オペランド という言葉が出てきますので これらの用語について説明します プログラム 1 行は 次の 4 つの部分からなっています 名称必須説明 1 ラベル変数名やジャンプ命令のとび先など 2 オペレーション必須命令そのもの 3 オペランド命令を補助する部分 4 コメント注釈表 3-1 命令の構成以下 順に説明します ラベル 1 カラム目から記述します オペレーションラベルがある場合は ラベルの後に 1 桁以上の空白をおいて記述します ラベルが無い場合は 2 カラム目以降から記述します 1 他のコンピュータでも使用できるような クロスアセンブラ と呼ばれるアセンブラが用意されている場合もありまるが これは身近に対応するコンピュータが無い場合にのみ テスト的に使用するものです コンピュータには特有の機能が多く これらの機能を生かすためには 専用のアセンブラ言語が必要なのです - 2 -
オペランドオペレーションに続いて 1 桁以上の空白をおいて記述します 通常の命令ではオペランドがありますが RET 命令など 無いものもあります オペランド部はさらに最大 3つの部分から構成されています たとえば LD GR1,KINGAKU,GR2 という命令の場合 オペランド部は GR1,KINGAKU,GR2 ですが この中の KINGAKU 部分を ディスプレースメント といいます コメントオペランドがある場合はオペランドの後に 1 桁以上の空白をおいて オペランドが無い場合はオペレーションの後に 1 桁以上の空白をおいて さらに ; を書いてから そのあとに記述します 整理しましょう 今 次のような命令があった場合 各部は下の表のようになります LABEL1 LD GR1,KINGAKU,GR2 ;COMMENT OF LD ラベルオペレーションレジスタオペランドディスプレースメントインデックスコメント表 3-2 命令の詳細詳細な構成 LABEL1 LD GR1 KINGAKU GR2 COMMENT OF LD 3.2 アセンブラ命令 アセンブラ命令は 実行する 命令ではなく プログラムの 骨格 のための命令で CASLⅡでは4つのアセンブラ命令が用意されています 3.2.1 START 命令プログラムの先頭に必ず書く命令で ラベル部がプログラム名になります オペランドにラベルを書くこともできますが 通常は 省略 でかまわないでしょう オペランドを省略すると プログラムの先頭から実行が開始されますが ラベルを書くと そのラベルのところから開始されます しかし わざわざこんなことをする必要もないので 普通は省略します 3.2.2 END 命令プログラムの最後に必ず書く命令で ラベルもオペランドもありません - 3 -
3.2.3 DC 命令 Define Constant の略で 名前の通り定数を確保します プログラムとして 実行 される命令ではありません DC は定数を定義する命令で 定数には次の4 種類があります 種類説明コーディング例 10 進定数 10 進数の数値を定義します DC 200 16 進定数 16 進の定数を定義します DC #00C8 文字定数文字列を定義します DC 'ABCDEFGH' ラベル定数アドレス LABEL1 表 3-3 DC 命令の種類 COMETⅡでは 1 文字は 8 ビットで表現されるため 上記の文字定数例は (8 文字ですから )4 語の領域を占めることになりますが CASLⅡでは 1 文字を 1 語に格納するとなっていますので 8 語の領域が確保されます 文字は各語の下位 8 ビットに定義され 上位 8 ビットはビットで '00000000' となります ここで 10 進とか 16 進とかを区別したのは あくまでもプログラムを分かりやすくするために区別したもので 10 進定数を 16 進で表現しても プログラムの動作はまったく代わりません たとえば DC 200 と DC #00C3 はまったく同じことになります 同様に DC 'A' は DC #0041 と書いても DC 65 と書いても まったく同じ結果になります ( ただし プログラムはたいへん分かりにくいものになりますが ) 後で詳しく述べますが CASLⅡでは変数そのものは属性を持ちません これに対し 一般的にコンパイラ言語では変数が属性を持っています たとえば C 言語で固定小数点で確保した変数は固定小数点演算でしか使用できませんし COBOL では文字型で定義した変数を計算に使用すれば コンパイル時にエラーになります - 4 -
CASLⅡでは 変数や定数の定義はいろいろな定義の仕方があるもんお これは単にプログラムを見やすくするためだけのもので 変数に属性を持っているわけではありません したがって文字として定義した変数を固定小数点演算で使用してもまったく問題はありませんし そん逆も大丈夫です CASLⅡでは 属性は命令が決める のです DC 命令は カンマでつないで 複数のオペランドを書くことができます DC 10 DC A DC #0041 は 次のように書いても まったく同じです DC 10, A,#0041 3.2.4 DS 命令 Define Storage の略で 領域を確保します DC 命令と違って 確保した領域に初期値は設定されず 単に領域を確保するだけです 3.2.5 リテラルについて リテラル という言葉について説明します いま プログラム中に 汎用レジスタ 1 を 16 進の X'F0F0' で論理積をとる という命令を記述するとします 普通は AND HF0F0 DC 1,HF0F0 #F0F0 というように記述します これは 面倒なので CASLⅡ では次のような書き方を認めています AND 1,=#F0F0 このように書くと アセンブラが = 以降を あたかも DC 命令で確保したかのように自動的に用意してく れます このような = 以下を リテラル と言います リテラルには DC 命令で記述できるのと同じ種類があります 種類 コーディング 説明 10 進リテラル =n nは 10 進数値 16 進リテラル =#xxxx xxxxは 16 進値 文字リテラル = cccc cccは文字 ラベルリテラル =LABEL1 表 3-4 リテラルの種類 - 5 -
3.3 マクロ命令 マクロ命令とは 複数の命令 ( ニーモニック ) をまとめてひとつの名前を付け あたかもひとつのニーモニックのようにしたもので C 言語の #include や COBOL の COPY 句 に似ています 単に複数のニーモニックの集合 1 ですから アセンブル時には普通のニーモニックと同じように処理されます 従って アセンブルの結果を見ますと 元のマクロ命令は無くなって ( 通常はコメントアウトされて ) 展開されたニーモニックがアセンブルされていることになります ニーモニックへの展開は アセンブル時の第 1 フェーズ 2 で行われます CASLⅡでは4つのマクロ命令が定義 3 されています IN OUT RPUSH RPOP 順に説明します 3.3.1 IN 命令 入力装置から文字を読み込む命令と定義されています IN 入力領域, 入力文字長領域 こんなコーディングになります IN INAREA,INLEN INAREA DS 256 INLEN DS 1 読み込んだ文字は INAREA へ先頭から格納されます 文字は 1 語に 1 文字づつ格納されます CASLⅡ では 1 文字は 8 ビットで定義されていますから 1 文字を 1 語に格納すると 8 ビット余ってしまい ます 文字は 1 語の右半分に格納され 左半分は全ビットが 0 に設定されます 読み込む文字数は最大で 256 文字になりますから この領域は 256 語以上確保しておいたほうが良いでしょう 確実に 100 文字以下しか読まないから 100 語しか確保しない でもかまいませんが 安全を見込んで 256 語用意したほうが良いでしょう 読み込んだ文字数が 256 以下のとき 余った領域は何も変化せず 元のままとなっています 1 マクロ命令にパラメータを与えて さまざまに展開する機能をもつアセンブラ言語もありますが CASLⅡでは定義されていません 2 第 4 章を参照 3 メーカーから提供されるもののほかに自分で作成することもできるのが普通ですが CASLⅡでは自作方法につ いて述べられていませんので マクロ命令としては 4 つのみになります - 6 -
また C 言語のように 文字の最後に NULL がセットされるということもありません INLEN には読み込んだ文字数が格納されます ここに 10 が格納されていれば INAREA から 10 語に文字が格納され 11 語目からは元のままになっています INLEN が-1 のときは EOF(End Of File) を意味します つまり 読み込むデータが無くなったので 何も読んでいない という意味です EOF になったときの INAREA の内容については定義されていませんが おそらく その前に読み込んだ内容 が残っていると思われます 3.3.2 OUT 命令 OUT 命令は IN 命令とは逆に 文字を書き出すマクロ命令です OUT 出力領域, 出力文字長領域 こんなコーディングになります OUT OUTAREA,OUTLEN OUTAREA DC 'ABCDEFGH' OUTLEN DC 6 OUTAREA の内容が先頭から順に (OUTAREA から順に )OUTLEN に格納されている文字数分 書き出されま す この場合 OUTAREA には 8 文字定義されていますが OUTLEN が 6 なので 'ABCDEF' の 6 文字が書き出 されます OUT 命令の場合も IN 命令と同様に 1 文字 1 語で書き出されます 書き出す文字は 語の右 8 ビットに格納しておきます 語の左半分は無視されますので 特に全ビットを 0 にしておく必要はありません 3.3.3 RPUSH/RPOP 命令 このマクロ命令は 汎用レジスタ 1~7 までの 6 個を順にスタックへ格納 (RPUSH) 取り出す (RPOP) 命令で す RPUSH マクロ命令は 次のように展開されます PUSH 0,GR1 PUSH 0,GR2 PUSH 0,GR7 また RPOP マクロ命令は次のように展開されます POP GR7 POP GR6 POP GR1 汎用レジスタの順番が RPUSH と RPOP で逆になっていることに注意してください ( マクロ命令なので気にす る必要はないかもしれませんが ) - 7 -
スタックは 最後に入れたものが最初に 取り出されます これらの命令の使用法は 5 章で説明します - 8 -
3.4 言語比較 ここで CASLⅡと C 言語 COBOL について 主な機能を比較してみましょう C 言語 COBOL CASLⅡ 変数定義 int char 他 PIC DC 10 進数 なし ゾーン付き 10 進パック 10 進 なし 変数の種類 固定小数点 (2 進 ) 固定小数点 (2 進 10 進 ) 変数は属性を持たないが 浮動小数点文字 文字列アドレス 浮動小数点文字 文字列 初期値として以下の定義が可能固定小数点文字 文字列 16 進の値アドレス 変数の大きさ 各種 各種 1 語のみ 領域定義 変数定義で代用 変数定義で代用 DS 配列 [ ] で記述 OCCURS 指標レジスタを使用して自分で管理 変数の再定義 UNION REDEFINES なし 転送 a=b の形式 MOVE レジスタ経由 判断 if IF CPA CPL 計算 数式を記述 COMPUTE レジスタを使用加減算のみ 繰り返し for while PERFORM 条件 分岐を使用して自分で管理 分岐 goto GO TO JUMP 複数分岐 case switch GO TO DEPENDING なし 関数 サブルーチ ルーチン名を記述 CALL CALL ン呼び出し 擬似変数 関数名 決められた幾つかのみ なし スタック なし なし PUSH POP で操作 マクロ機能ソースのコピー include デバッグ文 COPY IN OUT RPUSH RPOP 作成方法は未定義 表 3-5 言語比較 - 9 -