- 「メインフレーム・コンピューター」で遊ぼう - http://www.arteceed.net -

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部分の長さではありません。