ハウスキーピングあれこれ

By 神居 - Posted: 2008/12/03 Last updated: 2011/05/16 - One Comment

ハウスキーピング(プログラム冒頭での呼び出し元レジスター内容の保管やベースアドレスの設定処理)の処理はプログラマーによっていろいろな方法が行われるが基本は「リンケージ規約の遵守」です。決まり切った手順でもあるので一度スタイルを決めればずっと使い続けられます。
ここでは私自身が長年使ってきたコーディングのいくつかをサンプルとして紹介します。


オーソドックスなコード

レジスター保管域をハウスキーピングのコードの中に定義した例です。レジスター保管域のように実行中に参照することがないデータ領域にいちいち名前を付けるのも面倒なので私自身は好んで使っていました。
呼び出し元への復帰時にはGR15に復帰コードが設定されているものとしています。


モジュールの先頭にヘッダーを付ける

プログラムの冒頭にヘッダーを付けることはしばしば行われます。名前、アセンブル日付・時刻などはヘッダー情報の代表的なものです。複数のプログラムを結合して1つのロードモジュールにするような場合は各CSECTの名前も入れればダンプリストを見た際に識別しやすくなります。商用プログラムでは製品のバージョンやPTF用のパッチエリア、COPYRIGHT表示なども入れられます。
一般のプログラムは入口点のGR15にはプログラムの先頭アドレスが格納されていますから、ヘッダーの長さだけジャンプする無条件分岐命令を先頭に置いて、続いてヘッダーデータを書きます。GR15を基点にしてヘッダーの長さ+分岐命令の長さを指定してヘッダーを迂回します。
MSPとVOS3では&SYSDATCの代わりに&SYSDATEが使えます。


ヘッダー用マクロを作る

いちいちヘッダーを書くのが面倒、プログラムを分割して開発するがヘッダースタイルは統一したい、と言った場合はヘッダーを生成するマクロ命令を作ると便利です。MACROからMENDで囲まれた部分をMDHDRと言う名前のメンバーで作成します。プログラムではこのMDHDRマクロを書けばアセンブル時にマクロ内で定義したヘッダーデータが展開されます。
ヘッダーマクロのサンプルとそれを使ったサンプルを示します。


オーソドックスなコード(再入可能プログラム)

再入可能(リエントラント構造)プログラムは自分のプログラム内に書き込みデータを持つことができないので、レジスター保管域も定義できません。レジスター保管域をプログラムの外に確保するサンプルです。


GR13をベースレジスターに使う

再入可能である必要がないプログラムではレジスター保管域を示すGR13をベースアドレスにしたプログラムを作成することもできます。サイズが大きくなるプログラムでも、GR13,12,11とベースアドレスに使えるレジスターを1つでも多くすることができます。サンプルではレジスター保管域をプログラムの先頭に置き、GR13とGR12をベースレジスターにしています。
DC 17Fで68バイトしか定義していないのは間違いではありません。保管域の最初のワードはアセンブラー言語では未使用であることを応用しています。


一切のサブルーチンを呼ばないなら

あまりいいサンプルではありませんが、将来に渡っても絶対サブルーチンを呼ばないのならこのようにレジスター保管域を持たなくてもかまいません。OSのAPIはほとんどがSVC呼び出しなのでレジスター保管域を必要としませんが、データセットのアクセスに使うGET/PUTマクロなどAPIによってはGR13がレジスター保管域であることを要求するものもあるので注意します。


リンケージスタックを使う

リンケージスタックはESA/390から利用できる機能です。先頭のBAKR 14,0命令は現PSWの前半ワード内容とGR14の内容で後半ワードを生成した呼び出し元への復帰用PSW、および汎用レジスターとアクセスレジスターをスタックに保管します。最後のPR命令はスタックに保管されたPSWとレジスター2から14が復元されます。結果としてレジスターを復元して呼び出し元に戻ることになります。レジスター15,0,1はPR命令発行時の内容がそのまま渡ります。BAKRはスタックへのPUSH、PRはスタックからのPOPです。内部サブルーチンでもレジスターの保管を気にせずに済むので使うと便利な機能です。
MVSではリンケージスタックの利用は必須ではありませんし、使う使わないの選択は自由なので、自分が呼び出すサブルーチン(OSのAPIを含む)がリンケージスタックを使う保証はありません。そのためGR13には標準のレジスター保管域をポイントする方が間違いありません。この場合呼び出し元保管域のポインターにはアドレスの代わりに’F1SA’の4文字を設定する規約になっています。
現実的にはプログラムは最初に実行される時、OSが用意したレジスター保管域がGR13で渡されるため、GR13を他の目的で使わない限りわざわざ別に用意しなくても問題はおきないでしょう。(例えばQSAMのGET/PUTマクロの利用など)ただしプログラムがABENDした時のダンプには正しいSAトレースが出力されなくなります。自分は呼び出し元の保管域を使用しなくても、呼び出すプログラムのために標準通りの保管域を用意し、互いにチェインする代わりにF1SAを表示するのはレジスター保管域とリンケージスタックを混在させるためのMVSの決まり事なのです。テスト的に作成するプログラムでない限り規約通りに作成する方がいいでしょう。

リンケージスタックはMVS(z/OS)では当たり前に使える機能ですが、MSPとVOS3では注意が必要です。MSPではMAFと呼ばれる追加のハードウェア機構が必要で、VOS3ではIPLパラメーターにクロスメモリー機能を有効にするパラメーター(マニュアル記載なし?)が必要です。利用できない環境であれば、BAKR命令がS0DxのコードでABENDします。その場合はメーカーの担当SEに問い合わせてみて下さい。

Posted in MVS実践アセンブラー・プログラミング • • Top Of Page

One Response to “ハウスキーピングあれこれ”

Comment from tonkuma
Time 2008年12月8日 at 03:30

PL/Iの BEGIN(and/or PROCEDURE) BLOCK におけるハウスキーピングも解説していただけるとありがたいです(興味があります)。