PACKとUNPK(Unpack)
PACK,UNPK(Unpack):パック、アンパック
10進演算を行う際に使用する、10進数字文字と10進数変換を行う、CPU命令です。S/370アーキテクチャーでは加減乗除などの演算は、一般的には2進固定小数点を使用しますが、事務計算処理を行うプログラムでは10進演算も使われます。2進固定小数点では最大10桁(約+21億?-21億)までの数値しか扱えませんが、10進演算では31桁までの長さの数値を処理することができます。このため数百億?兆を超える桁数を必要とする大規模な会計業務などでは、10進演算も利用されます。
PACK命令
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- PACK DECIMAL,ZONEDEC DECIMAL DC PL8'0' ZONEDEC DC C'12345678'
命令実行後、ZONEDECにある8バイト(8文字)がパック形式に変換されます。10進演算を行うためには、数値がパック形式になっていなければなりません。
パック形式
+0 1 2 3 4 5 6 7 +-------------------------+ I 00 00 00 01 23 45 67 8F I +-------------------------+
0?9の10進数字は4ビットで表現できます。パック形式は10進数の各桁を4ビットで並べ、最後に符号を示す4ビットを付けたものです。1バイトには2桁の10進数字が格納できます。10桁の10進数は5バイト+符号桁で6バイトを必要とします。パック形式は演算には使用できますが、データとしてはただのバイナリーなので、表示や印刷には使えません。
符号は+にはCまたはF、?にはDが使われます。正確には+はA,C,E,F、?はB,Dとなっているのですが、通常のコーディングではAやBなどが使われることはありません。+符号にFを使うのはゾーン形式とパック形式の相互変換においてです。アセンブラーはパック形式の表現にはCとDを使用しています。以下のDC命令をアセンブルしてみると、パック10進数の符号にCとDが使われることがわかります。
PRINT DATA DIGIT31 DC PL16'1234567890123456789012345678901' NIGIT31 DC PL16'-1234567890123456789012345678901'
UNPK命令
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- UNPK ZONEDEC,DECIMAL DECIMAL DC PL4'1234567' ZONEDEC DC CL8' '
命令実行後、DECIMALにある4バイト(7桁+符号)がゾーン形式に変換されます。符号は最下位桁のゾーン部に設定されます。10進演算の結果を表示、印刷するためには、数値がゾーン形式になっていなければなりません。
ゾーン形式
+0 1 2 3 4 5 6 7 +-------------------------+ I F0 F1 F2 F3 F4 F5 F6 C7 I +-------------------------+
各バイトは上位4ビットのゾーン部と下位4ビットの数字部で構成され、1バイトが1桁を示します。ゾーン形式は事実上の文字列であって、10進数を文字化したものに他なりません。文字であるのでそのまま表示と印刷が行えます。ただし直接演算することができないので、端末やJCLなどからの入力データは一旦パック形式に変換し、再び表示や印刷のためにゾーン形式に変換します。
符号は最下位桁のゾーン部に設定されます。そのため、演算に使用したパック形式の符号がCまたはDの場合、最下位桁は Cn あるいは Dn となってしまい、数字として正しい表示ができません。そのためUNPK命令の後に、最下位桁のゾーン部にB’1111’をORすることがよく行われます。
----+----1----+----2----+----3----+----4----+----5----+----6----+----7-- UNPK ZONEDEC,DECIMAL OI ZONEDEC+7,C'0' :
サンプルでは無条件に+符号と扱っていますが、+と?両方の符号があり得る場合は、符号を判定して先頭や末尾に?記号をつけるなどの編集が必要です。作表処理などでは、符号や通貨記号を付ける位置を求めたり、3桁ごとにカンマで区切ったり、先行する0を空白に置き換えたりなど編集が求められます。これらの処理には、EDやEDMK命令を使うといいでしょう。
パック/ゾーン形式の解説、PACK/UNPK命令の機能や仕様、ED/EDMKの詳細は、「z/Architecture解説書」に詳説されています。
2進固定小数点(バイナリー)で済むなら、加減乗除などの演算には一般のADDやSUBTRACTを使うことを勧めます。10進数はメモリーにしか置けず、レジスターは使えません。常にメモリー間演算となります。バイナリー演算命令に比べれば、実行速度も遅く、命令長も長く余計にメモリーを使います。このような特性は知っておくべきです。現在では会計業務などのための、事務計算プログラムの多くはCOBOL言語で書かれています。アセンブラーで10進演算を行う必要性はそう多くないでしょう。ただしPACK/UNPK、ED/EDMK命令は、処理メッセージ・テキストの編集などで常に必要とされますから、マニュアルを見れば使える、と言う程度に理解しておくと応用が拡がります。
3 Responses to “PACKとUNPK(Unpack)”
Comment from kumi
Time 2012年11月21日 at 19:27
よろしくお願いします。
Comment from kamii
Time 2012年11月22日 at 08:42
Comment from kumi
Time 2012年11月21日 at 19:25
6バイトのエリアで 201212080000 と頭4バイトに数字が入っているとき
これを
F1F2F1F2F0F8 と取り出すには どうすれば いいのですか?