IPCS以外のVTAMトレースの解析プログラム(TAP)

By kamii - Last updated: 水曜日, 11月 12, 2008

VTAMのトレースデータはIPCSでもフォーマットできますが、NCPが提供するTAP(Trace Analysis Program)と言うプログラムを使うと、SNAのプロトコルをより詳細に編集してフォーマットすることもできます。今では使い機会も少ないでしょうが、いざと言うときのためにサンプルJCLを残します。MVS専用です。
だいぶ古いJCLなので最新のTAPでは若干変わっているかも知れません。以前はNCPのDIAGNOSIS GUIDEマニュアルに記載されていましたが今でも入手できるかはわかりません。
※2009/11月追記:最新のz/OS V1R11で、「Communications Server, ACF/TAP Trace Analysis Handbook」としてCSのマニュアル・ライブラリーに追加されていました。

ACFTAP実行JCLサンプル

Filed in ありがたいサンプルJCL

10.SYSINとSYSOUTのI/O

By kamii - Last updated: 水曜日, 11月 12, 2008

CPU命令だけを使っていても、あまり面白くないし、実用的ではありませんね。それに「アセンブラーではI/Oをどうやって処理するのだろう?」と言うことにも触れなければなりません。誰かに呼ばれるだけのサブルーチンやOSの出口ルーチン(これもOSから呼ばれるサブルーチン)でなければ、プログラムにI/Oはつきものです。

プログラムの基本的なINPUTとOUTPUTはこう定義することができます。ここでは実際にこのように定義されたDD文に基づく入出力先に対するI/Oのやり方を覚えて下さい。基本的なI/Oはアセンブラーでも大して難しくありません。コードを書くことだけに関して言えばCOBOLと大差ないのです。


QSAM(待機順アクセス法)

QSAMは順次データセットをアクセスするためのMVSのAPIです。正確にはDFSMS/DFPと言うデータ管理コンポーネントが提供するAPIです。CPUには命令としてのI/O命令(SSCH:Start Sub CHannel)もあります。しかしこのI/O命令を使って一般のプログラムが入出力を行うことはありません。たとえ命令解説書を読んで理解したとしても決してやってはいけません。MVSではI/OはすべてOS自身が一元管理します。I/Oに関するOSの機能はいくつかの階層に分かれていますが、一般のプログラムは、DFPと言うもっともアプリケーション寄りのコンポーネントにQSAMなどのAPIを使ってI/Oを要求します。
このAPIを呼び出すために使われるのがマクロ命令です。マクロはアセンブラーの機能でいくつかの命令をまとめたもので、定型的な処理などを行うために使われます。マクロを使わず直接CPU命令でDFPのAPIルーチンを呼び出すこともできますが、一般的ではありません。最初は(ほとんどのケースで最後まで)マクロ命令を使って基本的なアクセスの仕方を覚えましょう。

QSAMではデータセットをレコード単位にアクセスできます。上のJCLではDD文でSYSINとSYSOUTを定義してますが、データセットそのものを定義してもかまいません。QSAMを使ってアクセスする限り、DD文から先の実際のデバイスに関してはプログラムで意識する必要がありません。
なお、ここで解説するQSAM APIは従来からある24ビットモードのAPIです。31ビットモード・サポートのAPIについては解説しません。24ビットモードAPIはMVS、MSPおよびVOS3それぞれ互換があります。


簡単ですがQSAMによるデータセット(SYSIN,SYSOUT)のアクセス方法を紹介しました。アセンブラービギナーがファイルのI/Oのために最初に使うのがQSAMです。理由はビギナーでもわかりやすい簡単なインターフェースだからです。そのためQSAMは初心者向きのEASYなアクセス法だと誤解されがちですが、決してそれだけではありません。QSAMはアクセス法の中でも高いI/Oパフォーマンスを持ちます。後ろへ戻ったり、レコードをスキップして読んだりなどの細かな制御はできませんが、順次にアクセスすれば良いのなら、初心者でもそれなりの高速で動くI/Oプログラムが作れます。中級レベルのスキルのプログラマーが作ったBSAMやEXCP(ブロック単位アクセス)のプログラムより、初心者が作ったQSAMのプログラム(レコード単位アクセス)の方が恐らく性能が高いでしょう。QSAMは手軽に利用できますが、実際は奥深いアクセス法でもあります。

ざっとまとめるとこんな感じのサンプルになります。処理したいデータをSYSINから読んで、実行結果をSYSPRINT(SYSOUT)に出すものです。
COBOLと比べてもOPENはOPEN、CLOSEはCLOSE、READがGET、WRITEがPUTとソースを書く手間は高級言語とほとんど変わりません。I/Oそのもののコードを書くこと自体はそれほどむずかしくないでしょう。

Filed in S/370アセンブラー講座

11.入門編番外(おわりに)

By kamii - Last updated: 火曜日, 11月 11, 2008

アセンブラー基礎講座・入門編のおわりに番外編として実用的なヒントなどを少し。ここまでわかれば「OS/390アセンブラーハンドブック」を読んでもきっとその内容が理解できることと思います。
ハンドブックで述べていますが、アセンブラーのプログラムは「大部分が定石ともいうべきコードの書き方で、大半が構成される」と言えます。ここまでに解説したことはその定石コードを理解するために必要な前提知識でした。OS/390アセンブラーハンドブックには実際の現場で役立ついろいろなヒントが載っていますから、是非活用して下さい。
また実用品のプログラムを書くためには、MVS(MSP、VOS3)のAPIを使うことを避けて通れません。CPU命令だけの実用品プログラムはOS自身の割り込み処理ルーチンでもない限り、我々のレベルで書くことはまずありません。APIについては別のカテゴリーで新たな講座を始めようと思います。


レジスターに1を足す、1を引く

レジスターの値に固定値を加算、減算するには加減算命令の使用が思い浮かびます。しかし内容によっては加減算命令でなくても行う方法があります。

このテクニックはS/370アセンブラー言語では古くから使われています。いずれも命令の動作を応用した「へぇー、そうなんだ」と言うものの代表です。
覚えるとアセンブラーがちょっとわかってきた気がする、小さな幸せですが、実戦では多用されています。
(LA命令は24ビットモードで最大16MB-1、31ビットモードで最大2GB-1までしか扱えないのと減算は出来ないことに注意)
他にもいくつかの「へぇー、そうなんだ」が「OS/390アセンブラーハンドブック」にも載ってます。

ESA/390で追加された新しい命令です。BCTR命令では1しか引けませんが、これなら-32768から+32767の加減算が命令とは別のハーフワード数の定義なしでできます。講座ではS/370アーキテクチャーでの基本的な(伝統的な)命令しか解説してませんが、慣れたら命令リファレンスを見て便利そうな命令は積極的にトライして見て下さい。ただし富士通、日立でも動かすプログラムを作る場合は注意して下さい。特にzアーキテクチャーで追加されたような最新の命令セットはどこまで互換かは動かしてみないとわかりません。


文字列転送

これもESA/390での新しい命令で、MVSTを紹介します。C言語で言うstrcpyです。MVCやMVCLと違い転送する長さを指定しません。文字列の終端文字(NULLターミネート)で長さが認識されます。終端文字も含めて文字列が転送されます。

比較ならCLST命令があります。
ESA/390以降ではUNIXシステムサービスやLINUX自身をサポートするようになったため、LINUXの移植を意識した?と思われる命令がいろいろと追加で実装されています。それらはすべてが公開されていないようですが、一部はアーキテクチャー解説書に載っています。MVSTもCLSTも公開命令です。


わかりやすいロジックを心がけましょう

アセンブラー自体がわかりにくい、と言われてしまえばそれまでですが、わかりやすいプログラムがいちばんです。せっかくアセンブラーを使うのですからクールなロジックを書くのもいいのですが、他人が見てわかるプログラムでないといけません。多少冗長なロジックでも、メモリーをそれなりに使っても、CPUを少し余計に使っても、普通の人が見てわかるロジックにすることが実用品のプログラムでは大切です。LA命令で加算したり、BCTR命令で1を引いたりするのは、命令の動きや機能がわかっていれば簡単に解読できるので、そういうものはいいと考えます。ただしロジックを解読するのに複雑な数学の知識を必要としたり、あまりにもトリッキーなコードは考え物です。書いた人自身が生涯を掛けてメンテナンスするならともかく、ほとんどのプログラムがそうではありません。特にアセンブラー言語でのコーディングが要求されるプログラムはOSの出口ルーチンなどシステムプログラムの部類に入るものがほとんどです。そうでなくてもOSのコントロールブロックを参照したりするため、CPU命令そのものよりはOSの内部動作や構造に関する知識が求められます。命令自身で処理する部分はなるべくシンプルなコードにして保守する人の負担を減らした方がいいと考えます。いくらコメントをきちんとつけても難解なものは難解です。
このあたりはプログラマーのプライドにも関わってくるので賛否両論ありましょうが、自分自身の経験から言えば、やはり「シンプル・イズ・ザ・ベスト」です。そしてこの種の文句は自分の作ったプログラムに対してではなく、他人が作ったプログラムに対して生まれます。そもそも自分が書いたコードですら何年か経って見返した時、「これって何をやってたんだ?、何のために必要だったんだっけ?」「ひどいなぁ」と思うのですから、人が書いたコードなら尚更です。

実用ではたぶん必要としませんが、アセンブラーっぽい例題でひとつ例を挙げます。「ビットの数を数え上げる」

最初の方法はビットを左へ1つずつずらして、溢れたビットを足し算しています。溢れたビットが1なら+1になり、0なら0を足しても変わりません。命令の動きを知っていれば比較的容易に理解できます。
2番目の方法は雑誌に載っていたインテルのx86アセンブラーのサンプルをS/370用に直したものです。32ビットを4ビットずつ8つのブロックに分けて、4ビット単位に1の個数を求め、その考えを32ビットに拡張するものだそうです。4ビットをabcdと4つに並べた時、この4ビットの値は「8a+4b+2c+1d」となるそうです。これから「7a+3b+1c」を引くと、その4ビット中で1になっているビットの個数が求められる、と言うものです。
このページを書いた僕自身がよくわかっていないので、サンプルのコメントもただの命令動作の説明でしか書けませんでした。ちなみにその雑誌の記事では、上記2通りが紹介されていて、アセンブラーならではのコードとして紹介されていたのが「8a+4b+2c+1d」から答えを求めるものでした。その理由は実行する命令数が少ないからです。1番目の方法はソースコードの行数は少ないですがループするので、実際に実行される命令数は131命令になります。2番目の方法はソースコードの行数は多いですがループしないので、実際に実行される命令数は25命令で済みます。CPUの使用量、実行に掛かる時間で言えば、当然2番目の方法に軍配が上がります。

しかし実際の現場仕事としてのプログラムならどうでしょうか?少なくとも私にはよくわかりませんでした。今もわかってませんし突き詰めようとも思ってません。サンプル通りに書いたから動きますが、考え方だけ言われてゼロからコードを書けとなったら、きっとお手上げです。このトピックのネタにしたのも、アセンブラー講座の題材を探すためにめくってた昔の雑誌に載っていたのを見て、「これって(アセンブラーらしいプログラムだよと)言いたいことはわかるけど、こんなのみんなパッと見てわかんのかぁ」と思ったからです。

数学がわかっている人には常識かも知れないし、簡単じゃんこんなの、となるかも知れませんが、実際の現場には数学を知ってる人ばかりとは思えません。たった25命令で処理できるクールなロジックなのは認めますが、普通の人にこんなのわかるかぁ?って思います。CPU使用量は約5倍ですけど、たかが131命令。実際のところ大した違いではありません。数値計算や科学技術計算のプログラムなら別ですが、たいていのシステムプログラムではここまでこだわる必要性はないと考えます。それよりは後で別の人が、普通の人が見てもわかるプログラム、として書く方がいいと思います。アセンブラーらしいとか、CPUの機能を知り尽くしたようなコードもありですが、ソートやデータベースの検索エンジンなど、性能命のソフトはともかく、実用で作るプログラムはわかりやすくないと困ります。そうでなくてもアセンブラーなんてわかんないから困るって言うのが現実ですから。

Filed in S/370アセンブラー講座

09.ビット操作と論理演算

By kamii - Last updated: 火曜日, 11月 11, 2008

CPU命令の解説の最後はビット操作と論理演算(AND,OR,XOR)です。ビット操作はとてもアセンブラーっぽいプログラミング技法です。1バイトあれば8つの情報を持てますし、使いこなせるとプログラムはとってもスマートになります。


ビット操作の命令


論理演算命令(And,Or,Exclusive Or)

Filed in S/370アセンブラー講座

08.比較と分岐・ループ、サブルーチンの呼び出し

By kamii - Last updated: 月曜日, 11月 10, 2008

分岐とループは実用的なプログラムを作る上での基本でもあります。関連する機能でもある比較と併せてS/370アーキテクチャーにおける、分岐・ループ、サブルーチンの呼び出しなどについて解説します。基本の分岐命令(BC命令)については「四則演算の基本と条件分岐」を見て下さい。


整数比較命令(Compare)


文字(文字列)比較命令(Compare Character)

これらの他にMVCL命令の比較版であるCLCL命令もあります。使用する機会は少ないと考えるので講座では解説しません。必要ならば命令リファレンスマニュアルを参照して下さい。


ループ制御に使う分岐命令


サブルーチンの呼び出し

サブルーチンの呼び出しも分岐命令です。S/370(XA)命令セットではアドレスモードによって複数の命令を使い分けられるようになっています。

Filed in S/370アセンブラー講座

06.REXX データの分解

By takao - Last updated: 月曜日, 11月 10, 2008
いきなり「データの分解」が現れたのはREXXにおいて、他のプログラムを呼び出したりする際の引数、戻り値、入力を処理する、などにおけるキー”PARSE”がわからないと、やる気がなくなってしまうからです。PARSEはデータの分解を行う命令です。

シンタックス


形式は次のとおり

PARSE  [UPPER]  ソース  テンプレート

ソースから供給されたデータを、テンプレートに分解します。[UPPER]が入っていたら全部、大文字に変換します。
ソースに許されているキーワードは次のとおり
です。
次は、テンプレートに使われる表現です。
これだけじゃ、なんのことやらほとんどわからんと思います。例をあげますので、ゆっくり読んでください。

パターン


例1.
/* REXX */
DATA = “Hello, the world!”
PARSE VAR DATA w1 w2 w3
SAY w1 “/” w2 “/” w3
結果:
Hello, / the / world!

ブランクで文字を区切っていくというのが基本動作です。

例2.
/* REXX */
DATA = “Hello, the world!”
PARSE VAR DATA w1 . w3
SAY w1 “/” w2 “/” w3
結果:
Hello, / W2 / world!

.(ピリオド)プレースホールダはこのように、その場所の文字を無視させます。その結果、W2にはなにも割り当てられませんでした。 これで欲しい文字列だけを変数に割り当てられます。

例3.
/* REXX */
DATA = “Hello, the world!”
PARSE VAR DATA w1 “,” w2 w3
SAY w1 “/” w2 “/” w3
結果:
Hello / the world!

注意してみてください。Helloから ,(カンマ)がなくなりました。場所あわせのため,を使ったため、W1にはHelloだけが割り当てられたのです。
データを変えてみましょう。
例4.
DATA = “YAMADA,TAROU,34,TOKYO”
PARSE VAR DATA SEI “,” MEI “,” . “,” BASHO
SAY SEI “/” MEI “/” BASHO
結果:
YAMADA / TAROU / TOKYO

カンマ区切りのcsvから必要なデータだけを抜き出すといったことが簡単にできます。

データがカンマなどで区切られていない代わりに、場所が決まっているという場合の取り出し方は次のとおりです。コンピュータの出力を処理する場合などは、むしろこのほうが多いかも知れません。

/*——123456789012345678901234567890123456789 */
DATA = “00000001 3F563F56 CCF53422 33652100 …..”

このデータで、頭から8文字目まではアドレス、欲しいデータは23文字目から4文字だとします。(上の3422のところ)
書き方はいろいろ考えられます。
素直に1文字目から長さ8をアドレス、23文字目から長さ4が値とすると、
PARSE VAR DATA 1 ADDRESS +8 . 23 VAL +4 .
となります。

さて、今まで”"や数字で指定したところをプログラムの変数で処理できないでしょうか?そのためには、次のようにします。

DATA = “00000001 3F563F56 CCF53422 33652100 …..”
OFFSET = 23
PARSE VAR DATA 1 ADDRESS +8 . =(OFFSET) VAL +4 .

変数で位置を指定する場合は、絶対位置なら=、相対位置ならば+を明示してください。

ソース


変数を入力とする場合は、上のパターンの学習でさんざんやりましたから、いいでしょう。他の入力をご紹介します。

端末
PARSE PULL INPUT
SAY INPUT
PULLは、スタックのところで学んだように、スタックになにもなければ端末の入力待ちとなります。
その結果、エンターキーを押すまでの入力を得ることができます。

ARG
サブルーチンの引数を得る場合に使います。

CALL add 1,2
SAY RESULT
EXIT

add: PROCEDURE
PARSE ARG a,b
RETURN a + b


あとのソースはあまり使わないので、必要に応じてマニュアルを見てください。
Filed in REXX入門

07.文字(文字列)の操作

By kamii - Last updated: 日曜日, 11月 9, 2008

S/370アーキテクチャーではバイト(8ビット)が情報の基本単位です。EBCDICコードもそうですが、1文字は1バイトで示されます。事務処理や制御系のプログラムでは四則演算よりも文字(文字列)の取り扱いの方が多いでしょう。S/370はバイト操作に関する命令も豊富に持っています。


バイト転送命令


変換・探索・編集命令

以降の命令は、アセンブラービギナーには扱いが面倒なものです。こんなものもあるのか、と言う程度で名前だけ覚えるぐらいでもいいです。必要に迫られたら、リファレンスマニュアルなどを参考にしてトライして見て下さい。

Filed in S/370アセンブラー講座

米国人気質と日本人気質なのか?

By kamii - Last updated: 日曜日, 11月 9, 2008

週刊誌を見ていたらこんな本の広告があった。

中身を見ていないので内容については語らないが、広告にこんなくだりがあった。

長年ISVで海外のソフトウェア製品を扱ってまざまざ感じたことがある。大した顧客数じゃなかったから全部を知ってるわけではないし、実際はみんながみんなそうではないだろうが、企業の情報システム部門に携わる人達って昔に比べてだんだんネガティブになってきたように思える。パッケージソフトに関して言えば、開発元の人達の感覚って例えバグが多くても、それはそれ(もちろん直しますよ)、でもこのソフトの良さをもっと見てくれよ!とプラス思考が前に出てます。でも日本のお客さんは、これが出来なきゃだめ、あれも出来なきゃだめ、うちの会社の場合はこうでないとだめ、絶対問題が起きないって保証できます?…と結構マイナス思考で突いてくる人が多くなったように思う。はっきり言ってすんごーくストレスでしたよ。自分で作ったもんならわかったよ、好きにしてやるよ!って開き直ることもできるのですが、何せ人様が作ってるソフトで版権もありませんから結構板挟みってことも多かったです。もちろん人種で単純に分かれることではないけど、そんな風に感じてました。

これも某国産メーカーのソフト製品を作った時のことなんですけど、存在しないパラメーターやパラメーターに間違った値を設定した時など、いちいちエラーにしないで、無視したり、デフォルト値などに自動修正して、ワーニングのMSGは出すけど起動の処理は続けるって仕様で出したら、却下されたことがあった。必ずエラーにして落としちゃってくれって。そうしないとパラメーターに設定した値で動いているものだと勘違いしてしまい、別の意味で混乱を招くからだそうです。誤りなら誤りだとはっきりしてくれた方がいいって。小さな親切大きなお世話ってことでしょうか。MVSや当時やってたソフトも近年は多少のパラメーター・エラーぐらいじゃ起動は続けるっていうようになってたから、そういう風にデザインしたんですけど。やっぱり米国人と日本人の違いかなぁってその時も思いましたよ。もちろん作る上では止めちゃう方がはるかに楽ちんだけど。

希望と危機って言うほどではないが、ポジティブかネガティブって思うと何か妙にあてはまるかなぁ…

Filed in つぶやき・雑感

06.四則演算の基本と条件分岐

By kamii - Last updated: 金曜日, 11月 7, 2008

四則演算はS/370命令セットの中でも最も基本的な命令群の1つです。ハーフワード(半語:2バイト)とフルワード(語:4バイト)の2種類の整数値を取り扱うことができます。ただし乗除算だけは少し複雑です。また演算命令の結果として条件コードと言うものがセットされます。条件コードを具体的に知ってもらうために、分岐命令も追加で解説します。


加算・減算命令(Add,Subtract)


乗算・除算命令(Multiply,Divide)


2進数と10進数の変換

整数は2進整数なので、そのままでは人間が見てわかるアウトプットには使えません。まず10進数に変えて、さらに数字(文字)に変える必要があります。


分岐命令(Branch on Condition)

ちょっと横道へ逸れて、分岐命令を1つ解説します。加減算命令で出てきましたが、命令には実行した結果が条件コードとしてセットされるものがあります。条件コードがどうなるかを具体的に覚えるにはPSWを見るより、後続で実行する命令を分岐させる方がわかりやすいです。

Filed in S/370アセンブラー講座

FTPによるJES2スプールアクセス

By kamii - Last updated: 金曜日, 11月 7, 2008

FTPクライアントからz/OSのFTPサーバーにログインした後、QUOTE SITE FILETYPE=JESコマンドを入力すれば、以降のアクセスをデータセットではなくスプール内のジョブに切り替えることができます。JESスプールのアクセスモードではディレクトリは意味を持ちません。データセットのアクセスに戻す場合はQUOTE SITE FILETYPE=SEQと入力します。


LS

LSコマンドでスプール内のジョブをリストアップできます。表示できるジョブ範囲はFTPサーバー定義のJESINTERFACELEVELによって異なります。

JESINTERFACELEVELがどちらのモードで利用できるかは、FTPデーモン空間の起動プロシージャ(FTPD)のSYSFTPD DD文に定義されたパラメーターで指定されます。ジョブの実行結果をPCに転送し、使い慣れたエディター等を使って参照するには非常に便利な機能です。活用するにはJESINTERFACELEVELは2になっているといいでしょう。


GET JOBnnnnn PC側ファイル名

ジョブ内の転送可能なすべてのSYSOUTをPC側へ転送します。ジョブIDに.番号でSYSOUT番号を指定すればそのSYSOUTデータセットのみを転送します。「GET JOB30.5 D:\SYSOUT.txt」とすればジョブID JOB00030の先頭から5番目のSYSOUTデータセットをDドライブのSYSOUT.txtファイルとして転送します。なおGETでSYSOUTを転送してもスプール上から削除されることはありません。


DELETE JOBnnnnn

指定したジョブをスプールから削除します。実行中であればキャンセルされ削除されます。


PUT PC側ファイル名

指定したPCファイルをJCLとしてサブミットします。ホスト側ファイル名の指定は不要です。

Filed in 知っておくと便利なテクニックなど