Google
オフコン練習帳内を検索
インターネット全体を検索

NECオフコン関連
オフコン一般
情報
トップ  >  ロードモジュール

ロードモジュール

1 ジョブとして実行できるもの

Windowsではxxx.exeとかxxx.com、xxx.batなどのファイルが、プログラムとして実行することができます。それに対してA−VXで実行できるものは、ロードモジュール、ジョブストリーム、パラメータメンバの3種類があります。

このうちジョブストリームとパラメータメンバについては説明済みです。 ここではロードモジュールについて説明します。

2 ロードモジュール(LM)とは

Windowsでxxx.exeやxxx.comに相当するものが、ロードモジュールです。COBOL言語やFORTRAN言語でソースプログラムを作り、それをコンパイル/リンクした後にできる実行形式のものがロードモジュール(LM)です。A−VX付属のいろいろなユーティリティ(#ABCとか#MAPとか)もロードモジュールです。

ロードモジュールはロードモジュールライブラリ(LML)に格納します。


ロードモジュールは、ジョブとしてRUNコマンドやJCLの/RUN文、メニューなどから実行します。

3 ロードモジュール(LM)の構造

ロードモジュールを起動・実行するうえではロードモジュールの構造など知っていなくても問題ありません。

プログラムエラー発生時にもしかしたら役に立つかも、程度です。
後はソースプログラムをコンパイル/リンクするときに「このパラメータは何か?」と思ったときに役に立つかもしれない、程度でしょうか。

ロードモジュールをA−VXはセグメントという単位で管理しているようです。ロードモジュールを1つあるいはいくつかのセグメントに分割してLMLに格納しておき、ロードモジュール実行時に必要になる都度セグメントをメモリに読み込んで実行していくという仕組みのようです。

セグメント内もいろいろなものが混在しているわけではなく、このセグメントはデータ部、このセグメントはメインルーチンの部分、こっちのセグメントはコールされたプログラムの部分と分けられています。

セグメントのサイズは最大64キロバイトの可変の長さのようです。大きいプログラムなら64キロバイトのサイズのセグメントが複数個、小さいプログラムなら4キロバイトのセグメントが1個だけとかになります。

セグメントは2種類あるようです。

1つめはノンシェラブルセグメント。書き込みや読み込みができるセグメントで、データ部のようにデータを書いたり読んだりするような目的に使うセグメントのようです。Non-shareable、つまり実行したプログラム毎に状態が違うので共有できないセグメントということでしょうかね。

もう1つはリエントラントセグメント。書き込みができないセグメントで、命令部のように書き換わらない部分に使われるセグメントのようです。命令が勝手に書き換わったらウイルスみたいで嫌ですからね。re-entrantということでしょう。

ロードモジュールのセグメントの個数やそれぞれのサイズ、セグメントの種類などの情報はリンク時に出力されるマップを見ればわかります。

4 ロードモジュール(LM)の種類

ロードモジュールは4種類あるようです。

5 混合型LM

セグメント内にいろいろなものが混在しているわけではないと書いておきながら、いきなり混合型です。
1つのセグメント内にデータ部と命令部(手続き部)が混在しています。といってもリンカが出力するリンクマップを見るとセグメントの前半がデータ部、後半が命令部と分けられているようです。

1つのセグメントで構成され、サイズは最大63キロバイトです。

他の種類のロードモジュールとは実行モードが異なるので、実行スピードが劣るそうです。


このタイプだと最大でも63キロバイト分の大きさのプログラムしか作れません。 はるか昔1970年や1980年頃はオフコンの搭載メモリも1メガバイトあるかどうかというものでした。(今はパソコンでもメモリは数ギガバイトありますよね。)その頃に誕生したタイプのLMです。1メガバイトもないようなメモリでも実行できるタイプです。
なので今は積極的にこのタイプのLMを作るような場面はありません。

A−VX02のような最新のOSでも1970年や1980年頃に作ったロードモジュールがそのまま動きます、ということを表します。

ユーティリティにも混合型LMのものがいくつもあります。今でも動いている例としてよく挙がるので#BEDITで1セグメントでそのサイズは12キロバイトぐらい、#ALLOCがサイズが63キロバイトぐらいです。

混合型LMもさらに細かく分類すると4つの形態に分かれるようです。

混合型LMの4形態
形 態概 要
シンプル構造ノンシェアラブル型LM最も単純な構造のLM
リージョン構造LM手続き部をリージョン構造にオーバレイしているLM
トリー構造LM手続き部をトリー構造にオーバレイしているLM
シンプル構造リエントラント型LMシンプルノンシェアラブルをリエントラント化したLM

形態別に細かい説明もいまさら不要だと思うのでこれ以上は立ち入りません。

6 分離型LM

ノンシェラブルセグメント(つまりデータ部)のセグメントが1つ、リエントラントセグメント(つまり命令部)のセグメントが1つの計2個のセグメントで構成されるLMです。

データ部が最大63キロバイト、命令部が最大63キロバイトのプログラムまではこの分離型LMとして作ることができます。


これも古いタイプのロードモジュールで、たぶん「混合型LMだと大きなサイズのプログラムができない」と言われて作ったタイプかなと思います。でも2つのセグメント合わせても126キロバイトのサイズのロードモジュールしか作れません。

分離型LMも混合型LMと同様に実行スピードが劣るそうなので、今コンパイル/リンク時に積極的にこのタイプを選択する必要はありません。

混合型LMと同様に従来互換のためのLMです。

ユーティリティにもいくつか分離型LMがあります。#ABANAはノンシェラブルセグメントが63キロバイト、リエントラントセグメントが32キロバイトの分離型LMです。

ちなみにA−VX02でもこのタイプのLMを作ることはできます。COBOLコンパイラ(COBOL74規格の古い方のコンパイラね)でCSGパラメータにSEPARATE指定してコンパイルし、リンクするとできます。

分離LMもさらに細かく分類すると3つの形態に分かれるようです。

分離型LMの3形態
形 態概 要
シンプル構造ノンシェアラブル型/リエントラント型LMデータ部と手続き部が分かれた単純構造のLM
リージョン構造LM手続き部をリージョン構造にオーバレイしているLM
トリー構造LM手続き部をトリー構造にオーバレイしているLM

分離型LMも今新規に作ることもあまりないため、形態別に細かい説明もいまさら不要だと思うのでこれ以上は立ち入りません。

6 複数分離型LM

これが今の標準のタイプのLMです。

複数のセグメント構成で最大6メガバイトのLMを作ることができます。

ノンシェラブルセグメントがデータ部を集めたセグメント、リエントラントセグメントが命令部を集めたセグメントです。
最小構成でノンシェラブルセグメント1個、リエントラントセグメント1個の2セグメント構成。セグメントの組み合わせは自由で、例えばデータ部が多いならノンシェラブルセグメントが20個、リエントラントセグメントが1個みたいな構成もできます。
1セグメントのサイズは最小4キロバイト、最大64キロバイト。


COBOL85コンパイラでLMを作るとデフォルトでこのタイプのLMになります。

複数分離型LMもさらに細かく分類すると2つの形態に分かれるようです。

分離型LMの2形態
形 態概 要
シンプル構造ノンシェアラブル型/リエントラント型LMデータ部と手続き部が分かれた単純構造のLM
リージョン構造LM手続き部をリージョン構造にオーバレイしているLM

オーバレイ構造のLMは、1個の常駐セグメントと複数の非常駐セグメントから構成され、LMの実行時、常駐セグメントは常時メモリに存在し、非常駐セグメントは制御が移るたびにメモリにロードされます。非常駐セグメントはシステムが自動的に必要になればメモリ上に読み込み、不要になればメモリ上から削除されるため、メモリ空間を節約できます。
今のオフコンはメモリは数ギガバイト搭載しています。1セグメント64キロバイトです。(1キロ=0.001メガ=0.00001ギガです)それが複数あったとしてもメモリの節約量はわずかです。使用できるメモリが少なかった昔に使用メモリを節約するために用意された形態です。
シンプル構造のLMを作れば問題ないです。今ならオーバレイで作る必要はありません。オーバレイ構造はセグメント構成を考える必要があるので面倒です。

6 高速型LM

特殊なLMで、このタイプはシステムユーティリティしかないようです。

構造は複数分離型LMと同じなようです。普通のLMよりも高速に実行できるタイプのLMのようです。

調べたところ#MERGEや#SORTがこのタイプでした。

A−VX3時代に一時的にこのタイプのLMを出力する専用のコンパイラがありましたが、カスタマイズしすぎたのかこのコンパイラで出力したLMはA−VX4以降で動きません。このような問題があったからなのかA−VX4以降ではこのコンパイラは使用できない(インストールできない)&販売中止になっています。
私はこのコンパイラは製品説明ぐらいしか見たことがないので、詳細はよくわかりません。

7 ロードモジュールのセグメントを深堀してみる

COBOLプログラムをコンパイルしてリンクするとロードモジュールができます。

リンクするときに出力されるリンクマップを見るとセグメントの状態がわかります。それで少しセグメントについて説明したいと思います。

下があるプログラムをリンクした結果出力されたリスト(の一部)です。使用するところだけ載せています。
「MAP LIST」から「END OF MAP LIST」までがリンクマップです。

COBOL85で作成したプログラムをリンクしました。複数分離型LMです。

MAP LIST

RESIDENT PART  *******************************
***  DATA PART  ******************************
********  SEGMENT 0000 (0004)      SIZE = 00001928 (         6440)
     FILE CU-NAME  REV. COMPILED ATR  LANG SIZE                    FROM    -TO       ADDR              EXT/COMM SIZE SEG.
                                 STAC      000002A0 (         672) 00040100-0004039F
     SCF  LNK@OV   0018 62/03/14 DATA SYS  0000001A (          26) 000403A0-000403B9
                                                                                     LNK@OVSG 000403B4
     SCF  SYS@ID   V101 94/08/11 S006 SYS  00000002 (           2) 000403BC-000403BD
     SCF  SYS@ID   V101 94/08/11 S001 SYS  00000634 (        1588) 000403C0-000409F3
                                                                                     SYS@IDPB 000405E4
     CUF1 PERENT   0003 26/05/26 S100 CBL  000000AC (         172) 000409F4-00040A9F
                                                                                              0005099C COB@4APR      0001
                                                                                              000509FC COB@0VDP      0001
                                                                                              00050878 CHILD1        0001
                                                                                              000508F0 CHILD2        0001
                                                                                              00050BC8 COB@0UAP      0001
                                                                                              00050D90 COB@0XSR      0001
                                                                                              00050DE8 COB@0BEP      0001
     CUF1 CHILD1   0002 26/05/26 S100 CBL  00000064 (         100) 00040AA0-00040B03
                                                                                              0005099C COB@4APR      0001
                                                                                              000509FC COB@0VDP      0001
                                                                                              00050DE8 COB@0BEP      0001
                                                                                              00050D90 COB@0XSR      0001
     CUF1 CHILD2   0002 26/05/26 S100 CBL  0000009C (         156) 00040B04-00040B9F
                                                                                              0005099C COB@4APR      0001
                                                                                              00050BC8 COB@0UAP      0001
                                                                                              000509FC COB@0VDP      0001
                                                                                              00050DE8 COB@0BEP      0001
                                                                                              00050D90 COB@0XSR      0001
     SCF  SYS@0V   0022 01/03/16 DATA SYS  00000074 (         116) 00040BA0-00040C13
                                                                                              00050CB0 COB@9AAB      0001
                                                                                              00050F0C COB@9WWK      0001
     SCF  SYS@0U   0006 87/04/21 DATA SYS  0000004C (          76) 00040C14-00040C5F
                                                                                              00050CB0 COB@9AAB      0001
                                                                                              00050F0C COB@9WWK      0001
     SCF  SYS@9A   0005 91/05/21 DATA SYS  00000074 (         116) 00040C60-00040CD3
                                                                                     COB@9ACM 00040C60
                                                                                     COB@9ACC 00040C60
                                                                                     COB@9ASV 00040C70
                                                                                     COB@9AAB 00040CB0
                                                                                     COB@9ADB 00040CC0
     SCF  SYS@IT   0001 84/07/29 DATA SYS  00000010 (          16) 00040CD4-00040CE3
     SCF  SYS@9W   0006 93/03/08 DATA SYS  00000B28 (        2856) 00040CE4-0004180B
                                                                                     COB@9WDT 00040CE4
                                                                                     COB@9WWK 00040F0C
                                                                                     COB@9WPS 0004170C
     SCF  SYS@9G   0003 94/08/09 DATA SYS  0000011C (         284) 0004180C-00041927
                                                                                     COB@9GEP 0004180C
                                                                                     COB@9GCA 00041910
                                                                                     COB@9GDB 00041914

***  PROC PART  ******************************
********  SEGMENT 0001 (0005)      SIZE = 00000E74 (         3700)
     FILE CU-NAME  REV. COMPILED ATR  LANG SIZE                    FROM    -TO       ADDR              EXT/COMM SIZE SEG.
     SCF  LNK@OV   0018 62/03/14 PROC SYS  000000AA (         170) 00050000-000500A9
                                                                                     LNK@OVCA 00050026
                                                                                     LNK@OVLD 00050024
                                                                                     LNK@OVBC 00050000
                                                                                     LNK@OVBL 00050012
                                                                                     LNK@OVIT 00050070
     SCF  SYS@ID   V101 94/08/11 S003 SYS  000006FC (        1788) 000500AC-000507A7
                                                                                     SYS@ID   000500AC
                                                                                     SYS@IDPT 0005061A
     CUF1 PERENT   0003 26/05/26 S000 CBl  000000D0 (         208) 000507A8-00050877
                                                                                     PERENT   000507A8
     CUF1 CHILD1   0002 26/05/26 S000 CBl  00000078 (         120) 00050878-000508EF
                                                                                     CHILD1   00050878
     CUF1 CHILD2   0002 26/05/26 S000 CBl  000000AA (         170) 000508F0-00050999
                                                                                     CHILD2   000508F0
     SCF  SYS@4A   0004 84/07/28 PROC SYS  0000005E (          94) 0005099C-000509F9
                                                                                     COB@4APR 0005099C
                                                                                              00040CB0 COB@9AAB      0000
                                                                                              00050E34 SYS@ITEM      0001
                                                                                              00040F0C COB@9WWK      0000
                                                                                              00040C60 COB@9ACM      0000
     SCF  SYS@0V   0022 01/03/16 PROC SYS  000001CC (         460) 000509FC-00050B
                                                                                     COB@0VDP 000509FC
     SCF  SYS@0U   0006 87/04/21 PROC SYS  000001C6 (         454) 00050BC8-00050D
                                                                                     COB@0UAP 00050BC8
     SCF  SYS@0X   0001 92/03/30 PROC SYS  00000056 (          86) 00050D90-00050D
                                                                                     COB@0XSR 00050D90
                                                                                              00040CB0 COB@9AAB      0000
                                                                                              00041910 COB@9GCA      0000
                                                                                              00040C60 COB@9ACM      0000
     SCF  SYS@0B   0003 87/04/20 PROC SYS  0000004A (          74) 00050DE8-00050E
                                                                                     COB@0BEP 00050DE8
                                                                                              00040CB0 COB@9AAB      0000
                                                                                              00050E34 SYS@ITEM      0001
     SCF  SYS@IT   0001 84/07/29 PROC SYS  0000003E (          62) 00050E34-00050E
                                                                                     SYS@ITEN 00050E34
END OF MAP LIST

LOAD SEGMENT GRAPH LIST

         LM FORM = ADM 2
RESIDENT PART *******************
**** DATA PART ******************
          LSA = 004
LSEG-ID. ADDR  SIZE:HEX(DEC)  MAIN CU  ....-....1....-....2
LSEG0000 0000  01928( 6440)   PERENT  *******

**** PROC PART ******************
          LSA = 005
LSEG-ID. ADDR  SIZE:HEX(DEC)  MAIN CU  ....-....1....-....2
LSEG0001 0000  00E74( 3700)   PERENT  ****

END OF LOAD SEGMENT GRAPH LIST

まず大きく見るとDATA PARTとPROC PARTに分かれています。
DATA PARTがデータ部(つまりノンシェラブルセグメント)のセグメント群、PROC PARTが命令部(つまりリエントラントセグメント)のセグメント群になります。

もう少し詳細にみていきましょう。 DATA PARTの次の行に「SEGMENT 0000 (0004)」と書いてあります。ここから下はSEGMENT 0000の情報になります。0000はセグメント番号と言ってセグメントに順番につけられている番号です。セグメント番号が0のセグメントの情報になります。 DATA PARTにはセグメント番号0のセグメントしかありません。もしDATA PART中にSEGMENT 0001とかSEGMENT 0002とかがあれば、データ部に複数のセグメントがあることになります。今回はデータ部のセグメントは、セグメント番号0のセグメントが1つだけということになります。

次にPROC PARTを見てみます。「SEGMENT 0001 (0005)」があります。命令部にはセグメント番号0001のセグメントが1つだけあります。

今回はデータ部のセグメントが1つ、命令部のセグメントが1つ、合計2つのセグメントを持つ一番単純な複数分離型LMでした。(分離型LMも2つのセグメントを持ちますが、今回は複数分離型LMを指定してリンクしているので複数分離型LMです。)

データ部と命令部のセグメントは連番になっています。例えばデータ部のセグメントが4つ、命令部のセグメントが3つあるときは、データ部はセグメント番号0000、0001、0002、0003、命令部はセグメント番号0004、0005、0006のセグメントがあるはずです。

「SEGMENT 0000 (0004)」の括弧の中の4桁の数字はLSA番号といいます。セグメントをメモリ上に読み込んだ時の番号です。セグメント番号とはまた違う番号です。

シンプル構造ノンシェアラブル型/リエントラント型LMの場合は、セグメント番号+4の値がLSA番号になります。単純構造なので。

リージョン構造LMの場合は、オーバレイしているセグメントは同じLSA番号になります。例えばセグメント番号0008とセグメント番号0009がオーバーレイしているのならば「SEGMENT 0008 (0012)」「SEGMENT 0009(0012)」のように同じLSA番号になります。

「SEGMENT 0000 (0004)」の次にLNK@OVとかSYS@IDとかPERENTとかいろいろ書いてある行があります。これが何かというと、このセグメントを構成しているソースプログラムの名前です。xxx@xxxとなっているのはたいていシステムが用意したプログラムです。あなたが作ったCOBOLプログラムをリンクするとシステムが必要なプログラムをいろいろとくっつけてロードモジュールを作ってくれます。

私が作ったのはPERENT、CHILD1、CHILD2という3つの小さなプログラムだけなのですが、リンク時にシステムが必要なプログラムを自動的にくっつけてくれました。

セグメント番号0000のセグメントは12個のプログラムから構成されています。セグメント番号0001のセグメントは11個のプログラムから構成されています。

このようにロードモジュールは、複数のセグメント(混合型LMは1つのセグメント)から構成され、そのセグメントの中もたくさんのプログラムで構成されています。

「LOAD SEGMENT GRAPH LIST」から「END OF LOAD SEGMENT GRAPH LIST」の間はロードセグメントのサイズなどの情報をまとめたものです。

「LM FORM = ADM 2」の意味ですが、ADM2は複数分離型LMを意味します。ADM0が混合型、ADM1が分離型です。
「DATA PART」の「LSA = 004」はLSA番号が0004ということ。「LSEG0000 0000 01928( 6440) PERENT」はLSA番号が0004のセグメントはセグメント番号0000の1つだけで、そのサイズは十進数で6440バイト、メインのCUはPERENT。
「PROC PART」の「LSA = 005」はLSA番号が0005ということ。「LSEG0001 0000 00E74( 3700) PERENT」はLSA番号が0005のセグメントはセグメント番号0001の1つだけで、そのサイズは十進数で3700バイト、メインのCUはPERENT。

システム付属のユーティリティには、全て「#」で始まる名前が付いています。またこれらのユーティリティはSRVの「SYS@LML」というロードモジュールライブラリファイル内に入っています。「SYS@LBM」にもいくつか入っていますが、これらは特殊用途用のユーティリティです。