はじめに
メインフレームのアセンブラプログラムをCOBOLへ変換する作業では、算術演算命令だけでなくデータ形式を変換する命令も数多く登場します。その中でも頻繁に見かけるのが「PACK」と「UNPK」です。
私は組込み開発出身のため、バイナリデータの扱いには慣れていたものの、メインフレーム特有のゾーン形式やパック形式にはかなり戸惑いました。今回は、アセンブラからCOBOLへの変換作業で避けて通れないPACK命令とUNPK命令について紹介します。
PACKとは(ゾーン10進 → パック10進)
PACK命令は、ゾーン10進形式の数値をパック10進形式へ変換する命令です。ゾーン10進形式では、上位4ビットがゾーン(F)、下位4ビットが数字を表します。例として、'1' は F1、'2' は F2 となります。
例えば次のような文字データがあるとします。
'12345'
EBCDICコード上では各桁が1バイトずつ保持されます。これをPACKすると、
12 34 5C
のようなパック10進データに変換されます。最終バイトの「C」は符号(正)を表し、負の場合は「D」になります。
パック10進形式では1バイトに2桁の数値を格納できるため、データ容量を節約できます。また、メインフレームでは算術演算命令(AP、SP、MP、DPなど)がCOMP-3(パック10進)を前提としているため、計算前にPACKする処理が頻繁に現れます。
UNPKとは(パック10進 → ゾーン10進)
UNPK命令はPACKとは逆の処理を行い、パック10進形式のデータをゾーン10進形式へ展開します。
12 34 5C
というパック10進データをUNPKすると、
12345
という文字形式の数値へ変換されます。帳票出力や画面表示では人間が読める形式が必要になるため、演算後にUNPKが実行されるケースをよく見かけます。
COBOL変換時の考え方
アセンブラでは次のようなコードが記述されていることがあります。
PACK WKNUM, CHARNUM
...
UNPK CHAROUT, WKNUM
しかしCOBOLでは、データ定義次第でコンパイラが暗黙的に変換してくれます。
01 CHAR-NUM PIC X(5).
01 WK-NUM PIC S9(5) COMP-3.
MOVE CHAR-NUM TO WK-NUM.
このため単純に命令を1対1で置き換えるのではなく、「なぜPACKしているのか」「なぜUNPKしているのか」を理解することが重要です。アセンブラではデータ形式を明示的に変換していたものが、COBOLでは暗黙的に処理されることも少なくありません。
私が最初に戸惑ったポイント
組込み開発では数値を扱う際、バイナリ・16進数・浮動小数点を意識することが多くありました。一方、メインフレームではゾーン10進・パック10進・DISPLAY・COMP-3など独特の表現が登場します。
特にアセンブラ解析を始めた頃は、PACK、UNPK、ZAP、AP、SP といった命令が並んでいるだけで何をしているのか理解するのに苦労しました。しかし「文字形式」と「計算用形式」を変換しているだけと理解すると、処理の流れがかなり見えやすくなりました。
まとめ
PACKはゾーン10進形式からパック10進形式への変換、UNPKはその逆変換を行う命令です。メインフレームでは計算処理の前後で頻繁に使用されるため、アセンブラ解析を行う際の重要な基礎知識になります。
アセンブラからCOBOLへの変換では、単純な命令変換ではなく「データ形式がどのように変化しているか」を理解することが大切です。PACK/UNPKの役割を理解すると、アセンブラの処理意図を読み解きやすくなります。
メインフレームのオープン化案件では、このようなデータ形式の違いを理解することが、変換品質向上への第一歩だと感じています。