SIMHのPDP-11エミュレータを利用し、RK05にインストールされたUNIXv6のブートローダ「rkuboot」について調べています。これは「run」により作られますが、主たる処理は「fsboot.s」にあります。この中にあるルーチン「rmblk」は、サブルーチン呼び出しのリターンアドレスを操作しているようです。
rmblkが呼び出されると、まず「add $2,(sp)」があります。このままサブルーチンを終える場合もありますが、場合によっては、戻る直前に「sub $2,(sp)」しています。一方でrmblkの呼び出し元では「jsr pc,rmblk」の直後に「br callout」と「mov $buf,r1」が置かれています。普通なら、JSR命令で呼び出したサブルーチンから戻ってくると、その次の命令(ここであれば、BR命令)が実行されることになります。しかしrmblk側でリターンアドレスを操作しているので、戻り方に依っては命令を飛ばし(BR命令は実行されず) 、MOV命令から実行されます。かなり職人芸と言える技だと思います。
PDP-11上でUNIXv6が動作していた時代は、現在から比べると、CPU性能もメモリ容量も極めて限られていたので、このような芸当を駆使していたのだと説明されることがあります。確かにその通りかもしれません。そうであったとしても、このような芸当に走るのは、ちょっとやりすぎではないかと思わないでもありません。rmblkが正常終了したか異常終了したかに依って処理を分岐させたいのであれば、他の方法もあるだろうし、そうすることが困難だとも思えません。
0 件のコメント:
コメントを投稿