06.2CSECT名でプログラムのローディングを行う
LOADマクロでのローディングや、LINKマクロでの呼び出し時にEP/EPLOCで指定できる名前はロードモジュールのメンバー名です。CSECT名でのローディングや呼び出しはできません。動的構造のプログラムでCSECT名を使ってモジュールにアクセスするには少し工夫が必要です。
ロードモジュールの先頭にアドレスポインターフィールドを作る
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- COMMVCON CSECT , DEFINE CODE SECTION DC V(SUBRTN1) +00 POINTER TO SUBRTN1 DC V(SUBRTN2) +04 POINTER TO SUBRTN2 DC V(SUBRTN3) +08 POINTER TO SUBRTN3 DC A(0) --- RESERVED FOR FUTURE --- DC A(0) --- RESERVED FOR FUTURE --- DC A(0) --- RESERVED FOR FUTURE --- DC A(0) --- RESERVED FOR FUTURE --- DC A(0) --- RESERVED FOR FUTURE ---
//LKD EXEC PGM=IEWL, // PARM=('LIST,LET,MAP,XREF,NCAL') //SYSPRINT DD SYSOUT=* //SYSUT1 DD UNIT=SYSALLDA,SPACE=(TRK,(80,20)) //SYSOBJ DD DSN=MY.OBJLIB,DISP=SHR //SYSLMOD DD DSN=MY.LINKLIB(COMMSUBR),DISP=SHR //SYSLIN DD * INCLUDE SYSOBJ(COMMVCON) COMMON SUB RTNS VCON-TABLE INCLUDE SYSOBJ(SUBRTN1) SUB-ROUTINE1 INCLUDE SYSOBJ(SUBRTN2) SUB-ROUTINE2 INCLUDE SYSOBJ(SUBRTN3) SUB-ROUTINE3 : : //
LOAD EP=COMMSUBR LOAD OUR COMMON SUB-ROUTINES ST R0,ACOMM SAVE ENTRY ADDRESS LR R2,R0 COPY IT L RF,4(,R2) LOAD SUB-ROUTINE2 ENTRY LA R1,PLIST LOAD PLIST BASR RE,RF CALL SUB-RTN2 : :
いろいろなプログラムで使うさまざまな共通サブルーチンを1つのロードモジュールにまとめあげたライブラリーモジュールを作る場合、バインダーで連携編集されるモジュールのすべてのCSECTに先だってサンプルのようなV型アドレス定数(VCON)のフィールドを作ります。ここの部分のCSECTはなくてもかまいませんが、わかりやすくするためにもロードモジュールと同じ名前などでCSECTの定義をしておきましょう。結合したCSECT名を指定したVCONを必要なだけ並べます。最初のCSECTの前に定義してもいいですが、サブルーチンの数が多くきちんと管理するならば、VCONだけのソースメンバーを作った方がいいでしょう。
サンプルのJCLでバインドすれば、バインドされたロードモジュール名をCOMMSUBRとした場合、LOADマクロでロードされたCOMMSUBRの入口点アドレスがサンプルのCOMMVCON CSECTになります。先頭から+0番地の1ワードがSUBRTN1のアドレスが入ったポインターになり、先頭から+4番地の1ワードがSUBRTN2のアドレスが入ったポインターになります。SUBRTN2を呼ぶ場合はCOMMSUBRの先頭+4番地の内容をロードすればそれがSUBRTN2の入口点アドレスです。直接SUBRTN2の名前でLOADすることはできませんが、ロードしたモジュール内ののCSECTの位置はこのような方法で求めることができます。
このようなVまたはA型アドレス定数で他のモジュールやデータ・テーブル領域などをポイントするポインターフィールドの集合を「ベクターテーブル」と呼びます。
ロードモジュールにCSECT名のALIASを付ける
//LKD EXEC PGM=IEWL, // PARM=('LIST,LET,MAP,XREF,NCAL') //SYSPRINT DD SYSOUT=* //SYSUT1 DD UNIT=SYSALLDA,SPACE=(TRK,(80,20)) //SYSLIN DD DSN=*.ASM.SYSLIN,DISP=(OLD,DELETE) // DD DDNAME=SYSIN //SYSLIB DD DSN=MY.LINKLIB,DISP=SHR //SYSLMOD DD DSN=MY.LINKLIB(COMMSUBR),DISP=SHR //SYSIN DD * ALIAS SUBRTN1 ALIAS SUBRTN2 ALIAS SUBRTN3 //
LOAD EP=SUBRTN2 LOAD SUB-ROUTINE2 LR RF,R0 LOAD SUB-ROUTINE2 ENTRY LA R1,PLIST LOAD PLIST BASR RE,RF CALL SUB-RTN2 : :
最初の方法と異なりLOADマクロで直接CSECT名を指定できるようにする方法です。バインダーのALIAS(別名)機能でロードモジュールに別名を付けます。ALIAS制御文にCSECT名を指定すれば、それがそのまま別名になります。この例ではロードモジュール・ライブラリー内にはCOMMSUBR主メンバー名の他にSUBRTN1,SUBRTN2,SUBRTN3の副メンバー名が作成されます。
プログラムがLOADマクロのEP/EPLOCでSUBRTN2を指定すれば、ロードモジュール自体はCOMMSUBRがローディングされますが、入口点アドレスにはSUBRTN2のCSECTアドレスが通知されます。特定のCSECT部分だけを抜き出してロードすることはできませんが、指定したCSECTのアドレスを通知してもらうことはできます。なおGR1で通知されるモジュール・レングスもロードモジュール全体の長さであって、CSECT部分の長さではありません。