LOADマクロでのローディングやLINKマクロでの呼び出し時にEP/EPLOCで指定できる名前は、ロード・モジュールのメンバー名です。CSECT名でのローディングや呼び出しはできません。動的構造のプログラムでCSECT名を使ってモジュールにアクセスするには少し工夫が必要です。
ロード・モジュールの先頭にアドレス・ポインター・フィールドを作る
1 2 3 4 5 6 7 8 9 10 |
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- COMMVCON CSECT , DEFINE CONTROL 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 --- |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
//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 : : // |
1 2 3 4 5 6 7 8 |
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型アドレス定数のフィールドを作ります。ここの部分にCSECTは無くてもかまいませんが、わかりやすくするためにもロード・モジュールと同じ名前などでCSECTの定義をしておきます。結合したCSECT名を指定したVCONを必要なだけ並べます。最初のCSECTの前に定義してもいいですが、サブルーチンの数が多いのであればV型アドレス定数だけのソース・メンバーを作ってもいいでしょう。
サンプルのJCLでバインドすれば、バインドされたロード・モジュール名をCOMMSUBRとした場合、LOADマクロでロードされたCOMMSUBRの入口点アドレスは最初のサンプルCOMMVCON CSECTを指します。先頭から+0番地の1ワードがSUBRTN1のアドレスが入ったポインターになり、先頭から+4番地の1ワードがSUBRTN2のアドレスが入ったポインターになります。SUBRTN2を呼ぶ場合は、COMMSUBRの先頭+4番地の内容をロードすればそれがSUBRTN2の入口点アドレスです。直接SUBRTN2の名前でLOADすることはできませんが、ロードしたモジュール内のCSECTの位置はこのような方法で求めることができます。
このように、V型またはA型アドレス定数で他のモジュールやデータ・テーブル領域などをポイントするポインター・フィールドの集合を「ベクターテーブル」と呼びます。
ロード・モジュールにCSECT名のALIASを付ける
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//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 // |
1 2 3 4 5 6 |
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部分の長さではありません。