はじめに
メインフレームのアセンブラ資産を COBOL へ移行する際、必ずといっていいほど直面するのが、 レジスタを使ったパラメータ受け渡し の問題です。
アセンブラでは、処理対象データのアドレスをレジスタに設定し、そのままサブルーチンを呼び出すという書き方が一般的です。
しかし COBOL にはレジスタという概念がなく、同じロジックをそのまま再現することはできません。
今回は、アセンブラ的な「レジスタにアドレスを設定して共通サブルーチンを呼び出す処理」を、COBOL でどのように置き換えたかを紹介します。
アセンブラでよくあるパターン
LA R9,ARG1
BAS R14,ARGCHK
L R9,ARG2
BAS R14,ARGCHK
このコードでは、以下のような処理が行われています。
R9 に処理対象データのアドレスを設定
共通サブルーチン ARGCHK を呼び出し
サブルーチン側は「R9 の内容」を前提に処理
つまり、暗黙的な引数渡し(レジスタ依存) になっています。
COBOL での課題
COBOL には以下の制約があります。
レジスタという概念がない
CALL / PERFORM では明示的な引数が必要
アドレスではなく「データそのもの」を扱う
そのため、アセンブラのように「レジスタにアドレスを入れて呼び出す」という方法は使えません。
対応方針:中間バッファ方式
今回採用したのは、シンプルで移行しやすい方法です。
👉 レジスタの代わりに中間バッファを用意する
作業用バッファ(例:R9BUFF)を定義
呼び出し前に対象データをバッファへ MOVE
サブルーチンは R9BUFF を参照して処理
COBOL 変換例
● 呼び出し側
MOVE ARG1 TO R9BUFF
PERFORM ARGCHK
MOVE ARG2 TO R9BUFF
PERFORM ARGCHK
● サブルーチン側(イメージ)
ARGCHK SECTION.
* R9BUFF に対象データが入っている前提で処理
IF R9BUFF = SPACES
MOVE "NG" TO RESULT-FLAG
ELSE
MOVE "OK" TO RESULT-FLAG
END-IF.
ポイント解説
1. 「レジスタ=中間バッファ」に置き換え
アセンブラの R9 は「ポインタ」ですが、COBOL では ポインタ → データ保持領域(バッファ) として扱うことで構造を単純化できます。
2. 共通サブルーチンの汎用性を維持
元の ARGCHK は「R9 に入っているアドレス」を前提にしていましたが、COBOL では R9BUFF に対象データが入っている前提 に変更するだけで済みます。
3. 実務上のメリット
変換ルールが明確で迷わない
自動変換ツールでも扱いやすい
サブルーチンの再利用性を維持できる
レジスタ依存を排除し、保守性が向上
注意点(重要)
データサイズの不整合:ARG1 と ARG2 のサイズが異なる場合、R9BUFF のサイズ設計が重要
可変長データ:アセンブラでは「アドレス+長さレジスタ」で渡していたケースがある
パフォーマンス:MOVE が増えるため、大量データ処理ではわずかにオーバーヘッド
まとめ
アセンブラの「レジスタ渡し」は、COBOL ではそのまま再現できません。
今回紹介したように、中間バッファを介して明示的にデータを渡す という考え方に変換することで、安全かつシンプルに移植できます。
レジスタ依存のロジックを排除することで、COBOL 側の可読性・保守性も大きく向上します。