HELLO WORLD sobre el OS/360MVT
ジョブを実行したときのメインコンソールの様子
はじめに
今は昔、メインフレームありけり。ビルの1フロアを占領し、プログラムがこけると大量のABENDダンプを吐き出す怪物なり。
こないだ家で本を積みなおしていたらIBMメインフレームのアセンブラプログラミングの本が出てきました。アメリカの大学で学生が使う教科書のようで、電話帳なみに分厚い本です。
この本を読んでいて久しぶりにアセンブラでプログラムを書きたくなったので再チャレンジすることにしました。もっとも、実機はないのでNanoPi-NEO上で動くHercules上のOS/360MVT上でですが....。
やること
※Hercules上でのOS/360MVTシステム生成についてはここでは触れません。
パンチカードリーダ上のデータカード(HELLO, WORLD)を読み取り、ラインプリンタに出力する。
メインフレームの入出力
これから登場するIBM System/360の周辺機器を紹介します。
カードリーダ
データをパンチしたパンチカードをむしゃむしゃ食べる(読み取る)、なんとも地球に優しくない機械。1枚のパンチカードには80文字が記録できます。今でも端末の桁数にその名残があります。
Hercules上ではただのテキストファイルだけど、カードリーダがばりばりとパンチカードを食べてる様子を妄想しながら実行します。
ラインプリンタ
ジョブの実行結果を打ち出す、なんとも地球に優しくない機械。1行132文字。古い機械だと機械式だけど、私が大学で見たのは畳2畳分くらいある巨大なレーザープリンタだったなぁ。
プログラムがエラーすると大量のABENDダンプがここから吐き出され、プログラマを悩ませることに....。
コンソール
怪物と神官(オペレータ)のコミュニケーションツール。実機ではごく限られた人しか触れない。
磁気テープ
オープンリールの磁気テープを読み書きする機械。前のふたを開けてテープをセットし、ふたを閉めてから緑のボタンを押すとぐるぐる回る。
計算の途中結果やアセンブルされた機械語を一時保存したりするのに使用される。
プログラム
カードリーダにセットされた(HELLO, WORLDがパンチしてある)データカードをGETマクロで読み取り、MVC命令で出力領域にコピーし、ラインプリンタにPUTマクロで打ち出します。
//HELLO JOB CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1)
// EXEC ASMFCLG,REGION.ASM=256K
//ASM.SYSUT1 DD UNIT=SYSDA
//ASM.SYSUT2 DD UNIT=SYSDA
//ASM.SYSUT3 DD UNIT=SYSDA
//ASM.SYSGO DD UNIT=SYSDA
//ASM.SYSIN DD *
PRINT NOGEN
PRINTOUT START
STM 14,12,12(13)
BALR 12,0
USING *,12
ST 13,SAVEAREA+4
LA 13,SAVEAREA
*
OPEN (INFILE,INPUT,OUTFILE,OUTPUT)
MVC OUTAREA(132),SPACES
GET INFILE,RECORD
MVC OUTTEXT(80),INTEXT
PUT OUTFILE,OUTAREA
EOF CLOSE (INFILE,,OUTFILE)
*
L 13,SAVEAREA+4
LM 14,12,12(13)
BR 14
*
SAVEAREA DS 18F
INFILE DCB DDNAME=INFILE,MACRF=GM,BLKSIZE=80,LRECL=80, *
DSORG=PS,EODAD=EOF
OUTFILE DCB DDNAME=OUTFILE,MACRF=PM,BLKSIZE=132,LRECL=132, *
DSORG=PS
RECORD DS 0CL80
INTEXT DS CL80
SPACES DC CL1' '
OUTAREA DS 0CL132
OUTTEXT DS CL132
END
/*
//GO.OUTFILE DD SYSOUT=A
//GO.SYSUDUMP DD SYSOUT=A
//GO.INFILE DD *
HELLO, WORLD!!
/*
//
上記リスト中第1桁が'//'ではじまっているのはJCL(ジョブ制御言語、今でいうシェルスクリプトみたいなもの)の構文です。DDコマンドはプログラム内部のファイル名(DD名)と実際の入出力機器を結びつけるコマンドです。
実際のプログラムは"//ASM.SYSIN DD *"以下"/*"までの行です。
解説
プログラムの始まりと終わり
OS/360上ではプログラムはOSのイニシエータから呼び出されるサブルーチンのように書きます。
プログラムの始まりの部分はこういう風に書くのがお約束。
PRINTOUT START
STM 14,12,12(13)
BALR 12,0
USING *,12
ST 13,SAVEAREA+4
LA 13,SAVEAREA
呼び出されたときのレジスタの内容をSTM命令でメモリにセーブします。レジスタ12番にはこのプログラムのベースアドレスをBALR命令で入れます。その後自分自身のレジスタ保存領域の番地をレジスタ13番に入れます。
プログラムの終わりの部分はこういう風に書きます。
L 13,SAVEAREA+4
LM 14,12,12(13)
BR 14
保存してあるレジスタをLM命令で戻し、レジスタ14番に入っている戻り番地にジャンプします。
これを見て気づいた人もいるかもしれませんが、ARMのサブルーチンの呼び出し方はこれとほぼ同じです。違いはSystem/360の場合メモリの番地はベースレジスタ(上の例ではレジスタ12番)相対なのに対し、ARMの場合はプログラムカウンタ相対で指定するといった程度です。
なお、今回は大丈夫ですが、ベースレジスタ相対でアクセスできるのは4096バイトに限られています。
ファイルのオープンとクローズ
OS/360上ではUNIX系のOSと同様、入出力機器を「ファイル」として扱います。(コンソールだけは特別扱いで、WTO/WTORマクロで直接アクセスします)
これにより、入出力機器の違いを吸収しています。UNIX系OSでは当たり前の「なんでもファイル」の発想の原点がこんなところにあります。
ファイルの特性はDCB疑似命令で次のように書きます。
INFILE DCB DDNAME=INFILE,MACRF=GM,BLKSIZE=80,LRECL=80, *
DSORG=PS,EODAD=EOF
OUTFILE DCB DDNAME=OUTFILE,MACRF=PM,BLKSIZE=132,LRECL=132, *
DSORG=PS
行の後ろのアステリスク('*')は文が1行に収まらないときに72桁目に書きます。これは絶対に72桁目でないといけません。間違えるとアセンブラがエラーを出します。
'INFILE'、'OUTFILE'がこのプログラム上でのファイルの名前、いわゆるDD名です。MACRFはそのファイルに対しどういう入出力方式をとるかの指定です。GMだとGETマクロによる入力、PMだとPUTマクロによる出力です。LRECLはレコード長、1回のマクロ呼び出しで入出力される文字数、BLKSIZEはブロックサイズです。今回はカードリーダとラインプリンタなのでレコード長にひとしいですが、磁気テープのように1回の動作で複数レコードの読み書きができる場合はLRECLより大きい値になります。
ファイルは使用する前にオープンする必要があります。UNIX系のOSであれば標準入出力とエラー出力は常時オープンされていますが、OS/360の場合は明示的にオープンします。
OPEN (INFILE,INPUT,OUTFILE,OUTPUT)
使用が終わったファイルはCLOSEマクロでクローズして後始末します。
EOF CLOSE (INFILE,,OUTFILE)
ファイルの入出力
MVC OUTAREA(132),SPACES
GET INFILE,RECORD
MVC OUTTEXT(80),INTEXT
PUT OUTFILE,OUTAREA
最初にMVC命令で出力領域を空白文字で埋めます。埋めないと後ろにゴミが出力されます。
次にGETマクロで入力に指定したファイル(この場合はカードリーダ)からデータを読み込みます。
次に入力されたデータ(INTEXTに入っています)を出力領域にMVC命令でコピーします。
MVC命令の第1オペランド後ろのかっこ内の数字は「何バイトコピーするか」の指定です。
コピー元とコピー先が同じサイズであれば省略可能(アセンブラが決めてくれる)ですが、この場合は
異なるので明示的に指定します。
PUTマクロを呼び出して出力に指定したファイル(この場合はラインプリンタ)にデータを出力します。
実行
カードリーダに上記のカードデッキをかけます(実際にはHercules上でリーダにファイルを割り当てます)。
アセンブラが起動してソースをアセンブルし、リンケージエディタが実行モジュールを生成します。実行段階で次のJCLを読み取ります。'GO.INFILE'以下が入力データです。
//GO.OUTFILE DD SYSOUT=A
//GO.SYSUDUMP DD SYSOUT=A
//GO.INFILE DD *
HELLO, WORLD!!
/*
うまくいくとラインプリンタ(に割り付けたファイル)にジョブの実行結果が出力されます。
//HELLO JOB CLASS=A,MSGCLASS=A,MSGLEVEL=(1,1)
// EXEC ASMFCLG,REGION.ASM=256K
XXASM EXEC PGM=IEUASM,PARM=LOAD,REGION=50K 00020018
XXSYSLIB DD DSNAME=SYS1.MACLIB,DISP=SHR IEUD 00040016
//ASM.SYSUT1 DD UNIT=SYSDA
X/SYSUT1 DD DSNAME=&SYSUT1,UNIT=SYSSQ,SPACE=(1700,(400,50)), X00050018
XX SEP=(SYSLIB) 00060018
//ASM.SYSUT2 DD UNIT=SYSDA
X/SYSUT2 DD DSNAME=&SYSUT2,UNIT=SYSSQ,SPACE=(1700,(400,50)) 00070018
//ASM.SYSUT3 DD UNIT=SYSDA
X/SYSUT3 DD DSNAME=&SYSUT3,SPACE=(1700,(400,50)), X00080018
XX UNIT=(SYSSQ,SEP=(SYSUT2,SYSUT1,SYSLIB)) 00090018
XXSYSPRINT DD SYSOUT=A 00140000
XXSYSPUNCH DD SYSOUT=B 00150018
//ASM.SYSGO DD UNIT=SYSDA
X/SYSGO DD DSNAME=&LOADSET,UNIT=SYSSQ,SPACE=(80,(200,50)), X00160000
XX DISP=(MOD,PASS) 00180000
//ASM.SYSIN DD *
IEF236I ALLOC. FOR HELLO ASM
IEF237I 350 ALLOCATED TO SYSLIB
IEF237I 151 ALLOCATED TO SYSUT1
IEF237I 352 ALLOCATED TO SYSUT2
IEF237I 150 ALLOCATED TO SYSUT3
IEF237I 352 ALLOCATED TO SYSPRINT
IEF237I 151 ALLOCATED TO SYSPUNCH
IEF237I 352 ALLOCATED TO SYSGO
IEF237I 150 ALLOCATED TO SYSIN
EXTERNAL SYMBOL DICTIONARY PAGE 1
SYMBOL TYPE ID ADDR LENGTH LD ID 03.31 12/08/91
PRINTOUT SD 01 000000 00023D
PAGE 1
LOC OBJECT CODE ADDR1 ADDR2 STMT SOURCE STATEMENT F04MAR74 12/08/91
1 PRINT NOGEN
000000 2 PRINTOUT START
000000 90EC D00C 0000C 3 STM 14,12,12(13)
000004 05C0 4 BALR 12,0
000006 5 USING *,12
000006 50D0 C05E 00064 6 ST 13,SAVEAREA+4
00000A 41D0 C05A 00060 7 LA 13,SAVEAREA
8 *
9 OPEN (INFILE,INPUT,OUTFILE,OUTPUT)
00001E D283 C1B3 C1B2 001B9 001B8 17 MVC OUTAREA(132),SPACES
18 GET INFILE,RECORD
000032 D24F C1B3 C162 001B9 00168 23 MVC OUTTEXT(80),INTEXT
24 PUT OUTFILE,OUTAREA
29 EOF CLOSE (INFILE,,OUTFILE)
37 *
000056 58D0 C05E 00064 38 L 13,SAVEAREA+4
00005A 98EC D00C 0000C 39 LM 14,12,12(13)
00005E 07FE 40 BR 14
41 *
000060 42 SAVEAREA DS 18F
43 INFILE DCB DDNAME=INFILE,MACRF=GM,BLKSIZE=80,LRECL=80, *
DSORG=PS,EODAD=EOF
97 OUTFILE DCB DDNAME=OUTFILE,MACRF=PM,BLKSIZE=132,LRECL=132, *
DSORG=PS
000168 151 RECORD DS 0CL80
000168 152 INTEXT DS CL80
0001B8 40 153 SPACES DC CL1' '
0001B9 154 OUTAREA DS 0CL132
0001B9 155 OUTTEXT DS CL132
156 END
RELOCATION DICTIONARY PAGE 1
POS.ID REL.ID FLAGS ADDRESS 12/08/91
01 01 08 000015
01 01 08 000019
01 01 08 00004D
01 01 08 000051
01 01 08 0000C9
CROSS-REFERENCE PAGE 1
SYMBOL LEN VALUE DEFN REFERENCES 12/08/91
EOF 00004 000048 00031 0065
INFILE 00004 0000A8 00047 0013 0019 0033
INTEXT 00080 000168 00152 0023
OUTAREA 00132 0001B9 00154 0017 0026
OUTFILE 00004 000108 00101 0015 0025 0035
OUTTEXT 00132 0001B9 00155 0023
PRINTOUT 00001 000000 00002
RECORD 00080 000168 00151 0020
SAVEAREA 00004 000060 00042 0006 0007 0038
SPACES 00001 0001B8 00153 0017
NO STATEMENTS FLAGGED IN THIS ASSEMBLY
*STATISTICS* SOURCE RECORDS (SYSIN) = 30 SOURCE RECORDS (SYSLIB) = 2921
*OPTIONS IN EFFECT* LIST, DECK, LOAD, NORENT, XREF, NOTEST, ALGN, OS, NOTERM, LINECNT = 55
59 PRINTED LINES
IEF142I - STEP WAS EXECUTED - COND CODE 0000
IEF285I SYS1.MACLIB KEPT
IEF285I VOL SER NOS= MVTRES.
IEF285I SYS91342.T020452.RV000.HELLO.SYSUT1 DELETED
IEF285I VOL SER NOS= WORK01.
IEF285I SYS91342.T020452.RV000.HELLO.SYSUT2 DELETED
IEF285I VOL SER NOS= WORK02.
IEF285I SYS91342.T020452.RV000.HELLO.SYSUT3 DELETED
IEF285I VOL SER NOS= SYSRES.
IEF285I SYS91342.T020452.SV000.HELLO.R0000067 SYSOUT
IEF285I VOL SER NOS= WORK02.
IEF285I SYS91342.T020452.SV000.HELLO.R0000068 SYSOUT
IEF285I VOL SER NOS= WORK01.
IEF285I SYS91342.T020452.RV000.HELLO.LOADSET PASSED
IEF285I VOL SER NOS= WORK02.
IEF285I SYS91342.T020452.RV000.HELLO.S0000069 SYSIN
IEF285I VOL SER NOS= SYSRES.
IEF285I SYS91342.T020452.RV000.HELLO.S0000069 DELETED
IEF285I VOL SER NOS= SYSRES.
IEF373I STEP /ASM / START 91342.0331
IEF374I STEP /ASM / STOP 91342.0331 CPU 0MIN 01.36SEC MAIN 256K LCS 0K
XXLKED EXEC PGM=IEWL,PARM=(XREF,LET,LIST,NCAL),REGION=96K, X00210018
XX COND=(8,LT,ASM) 00220018
XXSYSLIN DD DSNAME=&LOADSET,DISP=(OLD,DELETE) 00240000
XX DD DDNAME=SYSIN 00260000
XXSYSLMOD DD DSNAME=&GOSET(GO),UNIT=SYSDA,SPACE=(1024,(50,20,1)), X00280000
XX DISP=(MOD,PASS) 00300000
XXSYSUT1 DD DSNAME=&SYSUT1,UNIT=(SYSDA,SEP=(SYSLIN,SYSLMOD)), X00320018
XX SPACE=(1024,(50,20)) 00340000
XXSYSPRINT DD SYSOUT=A 00360000
IEF236I ALLOC. FOR HELLO LKED
IEF237I 352 ALLOCATED TO SYSLIN
IEF237I 150 ALLOCATED TO SYSLMOD
IEF237I 151 ALLOCATED TO SYSUT1
IEF237I 352 ALLOCATED TO SYSPRINT
F128-LEVEL LINKAGE EDITOR OPTIONS SPECIFIED XREF,LET,LIST,NCAL
DEFAULT OPTION(S) USED - SIZE=(131072,18432)
CROSS REFERENCE TABLE
CONTROL SECTION ENTRY
NAME ORIGIN LENGTH NAME LOCATION NAME LOCATION NAME LOCATION NAME LOCATION
PRINTOUT 00 23D
LOCATION REFERS TO SYMBOL IN CONTROL SECTION LOCATION REFERS TO SYMBOL IN CONTROL SECTION
ENTRY ADDRESS 00
TOTAL LENGTH 240
****GO DOES NOT EXIST BUT HAS BEEN ADDED TO DATA SET
IEF142I - STEP WAS EXECUTED - COND CODE 0000
IEF285I SYS91342.T020452.RV000.HELLO.LOADSET DELETED
IEF285I VOL SER NOS= WORK02.
IEF285I SYS91342.T020452.RV000.HELLO.GOSET PASSED
IEF285I VOL SER NOS= SYSRES.
IEF285I SYS91342.T020452.RV000.HELLO.SYSUT1 DELETED
IEF285I VOL SER NOS= WORK01.
IEF285I SYS91342.T020452.SV000.HELLO.R0000070 SYSOUT
IEF285I VOL SER NOS= WORK02.
IEF373I STEP /LKED / START 91342.0331
IEF374I STEP /LKED / STOP 91342.0331 CPU 0MIN 00.09SEC MAIN 128K LCS 0K
XXGO EXEC PGM=*.LKED.SYSLMOD,COND=((8,LT,ASM),(4,LT,LKED)) 40360018
//GO.OUTFILE DD SYSOUT=A
//GO.SYSUDUMP DD SYSOUT=A
//GO.INFILE DD *
//
IEF236I ALLOC. FOR HELLO GO
IEF237I 150 ALLOCATED TO PGM=*.DD
IEF237I 352 ALLOCATED TO OUTFILE
IEF237I 150 ALLOCATED TO SYSUDUMP
IEF237I 150 ALLOCATED TO INFILE
HELLO, WORLD!!
IEF142I - STEP WAS EXECUTED - COND CODE 3520
IEF285I SYS91342.T020452.RV000.HELLO.GOSET PASSED
IEF285I VOL SER NOS= SYSRES.
IEF285I SYS91342.T020452.SV000.HELLO.R0000071 SYSOUT
IEF285I VOL SER NOS= WORK02.
IEF285I SYS91342.T020452.SV000.HELLO.R0000072 DELETED
IEF285I VOL SER NOS= SYSRES.
IEF285I SYS91342.T020452.RV000.HELLO.S0000073 SYSIN
IEF285I VOL SER NOS= SYSRES.
IEF285I SYS91342.T020452.RV000.HELLO.S0000073 DELETED
IEF285I VOL SER NOS= SYSRES.
IEF373I STEP /GO / START 91342.0331
IEF374I STEP /GO / STOP 91342.0331 CPU 0MIN 00.03SEC MAIN 8K LCS 0K
IEF285I SYS91342.T020452.RV000.HELLO.GOSET DELETED
IEF285I VOL SER NOS= SYSRES.
IEF375I JOB /HELLO / START 91342.0331
IEF376I JOB /HELLO / STOP 91342.0331 CPU 0MIN 01.48SEC
Author And Source
この問題について(HELLO WORLD sobre el OS/360MVT), 我々は、より多くの情報をここで見つけました https://qiita.com/jo3vpsmochi/items/034e9543f7fbb12ecd17著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .