2026-03-07

PDP-11のJSR命令の挙動と時代背景

PDP-11のJSR命令は、サブルーチンを呼び出すために使われます。x86におけるCALL命令のようなものです。x86に限らず、Z80でも6800でも、同様の命令が存在します。使うには、x86なら「CALL サブルーチン」のようにします。戻り番地はスタックに積まれているので、サブルーチンでは「RET」するだけです。

 

ところがPDP-11では「JSR レジスタ, サブルーチン」のようにしています。このとき戻り番地がレジスタに入りますが、レジスタをR7(=PC) とするなら、戻り番地はスタックに積まれます。要するにx86や6800などと同じ挙動です。サブルーチンを呼び出す命令で、なぜレジスタが出てくるのか分からず、Geminiに相談してみました。Geminiの応答は、自信たっぷりに返事をしますが、必ずしも正しいとは限らないので、話半分に聞いておく必要がありますが、それなりに納得できました。

 

Geminiが言っていたのは、PDP-11が登場した頃の時代背景が理由として考えられるそうです。その要点は、つぎのようなものでした。

  1. 当時は、アーキテクチャとしてスタックが今日のように一般的ではなかった。
  2. サブルーチン呼出し命令の直後に引数を置いておくテクニックが存在した。
  3. コードとデータの分離が不完全で、職人技的技法としてコードを書き換えることもあった。 

 

x86などでは、サブルーチンに与える引数は、レジスタに持つことが多く、少なくともCALL命令の直後に置いておくことはありません。しかも、8080の頃ならいざ知らず、80386以降のプロテクションモードの時代では、実行中にコードを書き換えることはなく、そんなことをしたら保護違反になってしまいます。

 

手元に、共立出版が1978年に発行した『マイクロコンピュータのプログラミング』という本があります。この中で「プログラム技法」(中西正和)では、「2.6 命令の中に命令を作る」として、今日では考えられないテクニックが紹介されています。ここで書かれているのは、バイナリ列「01 FE FF」 があったとすると、先頭から見れは「LXI B,0FFFEH」だが、2バイト目から見れば「CPI 0FFH」と見做せるし、3バイト目から見れば「RST 7」と見做せるというものです。まさに職人技です。そうかもしれないけど、そこまでするかという感じです。このようなテクニックがもてはやされるのは、メモリも少なく、(今日からすると)CPUも遅いという時代背景があるためだと思います。

 

PDP-11のJSR命令における不思議なレジスタの存在も、当時のプログラミング事情として「インライン引数」というものが存在したという時代背景が根底にあるようです。このような事情を知らないと、PDP-11のJSR命令の挙動が理解できない事を学びました。

0 件のコメント:

コメントを投稿