2026-03-28

「Making a Disk From Tape」と「Booting UNIX」の対称性

SETTING UP UNIX - Sixth Edition」の「Making a Disk From Tape」と「Booting UNIX」は、手順が対称的になっていることに気づきました。

 

「Making a Disk From Tape」では、細部を省略すると、次のような手順です。

  1. TU10コードをフロントパネルから入力して実行する。
  2. mbootがロードされるので、実行されると、プロンプト「=」が出力される。
  3. tmrkなどを入力することで、テープからディスクにコピーが行われる。

 

これに対して「Booting UNIX」では、次のような手順です。

  1. RK05コードをフロントパネルから入力して実行する。
  2. rkubootがロードされ、実行されると、プロンプト「@」が出力される。
  3. rkunixなどを入力することで、ディスクからカーネルが起動する。

 

「Making a Disk From Tape」の処理を追いかけてくることで、UNIXv6が動作する以前の世界が理解できました。

RK05は2種類ある

「RK05 disk drive maintenance manual」(DEC-00-HRK05-C-D)に記載されている「Table 1-1 Performance Specifications」には「Sectors(records)」として「4872 (12 per revolution)/6496 (16 per revolution)」とあります。これは何でしょうか。

 

RK05は、片面203シリンダ(含予備)なので、両面ならば406トラックあります。406×12=4872ですし、406×16=6496です。計算は合っていますが、どういう意味でしょうか。Geminiに相談したら、RK05は、1シリンダが12セクタの製品と16セクタの製品が存在したのだと回答しました。そうなのかもしれません。しかし裏付け資料が見つからないので、真偽が定かではありません。

 

UNIXv6の「rk.s」には、「div $12.,r0」という処理があります。この結果がRKDAレジスタ(777412番地)に入ることになるので、12セクタのための処理なのでしょう。しかし、もし16セクタのRK05があるとするならば、その容量を活かせていないことになります。

 

RK05に12セクタ版と16セクタ版が存在すると仮定して、UNIXv6が自動判別する処理を組み込むのは、当時の歴史的事情としては許されなかったのではないかと推測します。どちらかい決め打ちするのであれば、12セクタ版にしておいた方が無難と判断したのかもしれません。 

 

 

tm.sのtreadとrk.sのwblk

スクリプト「run」で作られる「tmrk」の処理の中心は「mcopy.s」にあります。最も重要なのは、「tread」と「wblk」を呼び出して、512バイト(256ワード)のコピーを指定回数分だけ繰り返しているところです。

 

「tread」は「tm.s」にあります。「wblk」は「rk.s」にあります。両者を見比べると、テープを操作するかディスクを操作するかという事だけではなく、大きく違うのですが、論理的には対称になっているはずです。「wblk」の方がシンプルで、「tread」は複雑です。その複雑さに目を奪われてしまうことなく、対称性に注意すれば、「tread」が何をしようとしているのか見えてくると思います。 

mcopy.sにおいて「illegal digit」が出力された場合の挙動

SETTING UP UNIX - Sixth Edition」の「Making a Disk From Tape」の手順に従って「tmrk」を呼び出すと、「disk offset」、「tape offset」、「count」の入力が求められます。これは「mcopy.s」のルーチン「numb」が呼ばれることで、キーボードから入力された数値がR0に入ります。ここで数字以外を入力すると「illegal digit」というエラーメッセージを出力して、「rts pc」が実行されます。ここで気になるのは、一体何処にもどるのでしょうか。

 

「tmrk」の中で「jsr pc,numb」として呼び出されている訳ですが、「tmrk」の中に戻るわけではないようです。エラー発生時に処理を追いかけていくと「tst (sp)+」をした後で「rts pc」となっています。この「tst (sp)+」が重要です。オペコード「TST」というのは、オペランドを評価してフラグをセットする命令です。普通は直後に条件分岐命令が続きます。しかしここでは「rts pc」が続いていて、フラグの状態には影響されません。

 

要するにここでは、TST命令である必要はなく、「(sp)+」として、SPが変化する事が重要なのです。SPを変化させることで、「tmrk」から呼び出された際の戻り番地を捨て、その上位にある「mboot」に戻るためのテクニックだと思います。そうなら、それが分かりやすいプログラムを書けば良いではないかと思うところですが、こういう職人芸的なプログラムを書くところが当時の時代背景としてあったのでしょう。 

「SETTING UP UNIX - Sixth Edition」の「Making a Disk From Tape」におけるmbootとtmrkの関係

SIMHのPDP11エミュレータを利用し、UNIXv6について学ぼうと考えています。同様の志を持つ方は少なくなく、オンラインでも書籍でも数多くの情報があります。しかしながら、それらはUNIXv6がディスクにインストールされていることを前提としており、「SETTING UP UNIX - Sixth Edition」の「Making a Disk From Tape」について言及されていないように思います。それでも別に構わないのですが、いきなりカーネル本体に取り組むより、例え多くの情報が蓄積されているとしても、まずはPDP-11のCPU本体や周辺機器の扱いに慣れる意味で、「Making a Disk From Tape」の手順や、その処理に精通しておくことにしました。

 

「Making a Disk From Tape」では、TU10の先頭ブロックをロードするコードが提示されています。PDP-11実機であれば、これをフロントパネルから入力し実行することで、配布テープの先頭ブロックがメモリにロードされます。これは、スクリプト「run」で作成される「mboot」であることを突き止めました。これが実行されると、プロンプト「=」が出力され、入力待ちになります。導入手順では「tmrk」と入力することになっていて、これをおこなうことで、配布テープからディスクにUNIXv6がコピーされます。

 

「mboot」も「tmrk」もスクリプト「run」によって作成されるa.out形式ファイルです。しかし両者は独立している訳ではないようで、「mboot」が主、「tmrk」が従の立場で動いているようです。このような主従関係と考えるのは、以下のような挙動だからです。

 

まず「mboot」が0番地からロードされ、実行されると、まず最初に自分自身を137000番地に移して、以降はそちらで実行を続けます。これは、「tmrk」などが0番地からロードされた際に、「mboot」が壊されないためと思われます。この挙動から、「mboot」が主で、「tmrk」が従と見做せます。 

 

さらに「mcopy.s」のでは、文字列を出力するため「jsr pc,4(r5)」のようなサブルーチン呼び出しが存在します。ここでR5は、「tmrk」では設定されていません。「mboot」の方で設定されていることが前提となっています。このような前提で「tmrk」が動作している事実が、主従関係があると判断する理由です。

 

また「tmrk」が実行されると、「disk offset」、「tape offset」、「count」の入力を求め、その入力に応じてテープからディスクにコピーすると、実行を終了してしまいます。実行終了後にどうなるかと言うと、「mboot」に戻るのです。この挙動を見ても、「mboot」が主で、「tmrk」が従だとわかります。

 

「Making a Disk From Tape」の手順6では、「tmrk」の代わりに「htrk」、「tmrp」、「htrp」などを使う場合の記述があります。これらのプログラムは調査していませんが、おそらく「tmrk」と同様だろうと思います。 

2026-03-22

mbootとUnix-v6-Ken-Wellsch.tap

SETTING UP UNIX - Sixth Edition」の「Making a Disk From Tape」で行われた処理について調べています。ここで書かれている手順の概略は次の通りです。

  1. PDP-11のフロントパネルを操作し、100000番地からTU10コードを入力し、実行する。
  2. テープから先頭ブロックが0番地に読み込まれるので、実行する。これは「mboot」です。
  3. 「mboot」の中でプロンプト「=」が出力されるので、テープの内容をディスクに書き込むプログラム名を指定する。ドキュメントでは「tmrk」が指定されています。「mboot」は、指定されたプログラム「tmrk」をテープから探し、メモリにロードし、制御を移します。
  4. 「tmrk」が実行されると、指定位置から指定長をテープから読み込み、ディスクに書き出します。

 

UNIXv6が出た当時は、これらの手順を実機PDP-11/40などでおこなったのでしょうけれども、21世紀に生きる我々はSIMHのPDP11エミュレータを使います。そしてテープイメージには、ファイル「Unix-v6-Ken-Wellsch.tap」を使います。

 

「mboot」は、スクリプト「run」によると、「tpboot.s」、「tty.s」、「tm.s」からできています。これらのソースを参照し、SIMHのPDP11エミュレータのデバッグ機能を駆使し、時々Geminiとの対話を繰り返しながら、解析しました。なんとか「mboot」の動作は理解できた気がします。動作の概略は、以下のようになっています。

  1. TU10コードにより、「mboot」はメモリ番地0からロードされます。「mboot」の目的は、ユーザが指定した「tmrk」などのプログラムをメモリ番地0からロードして制御を渡すことなので、このままではよくありません。そこで自分自身を上位に移し、プログラムがロードされる場所を空けておきます。上位のメモリ番地は137000のようです。
  2. プロンプト「=」を出力し、ユーザからプログラム名を入力してもらい、それをテープから検索します。
    1. プログラムを入力する際、「@」が入力されると、それまでの入力が全て取り消されます。また「#」が入力されると、その直前の入力が取り消されます。
    2. 入力された文字列(「tmrk」など)がテープに存在するか検索します。テープファイル「Unix-v6-Ken-Wellsch.tap」を調べたところ、先頭ブロックには「mboot」が格納されていますが、その次には「hboot」が入っていることがわかりました。その次からTP(V)形式のディレクトリが続きます。PDP11のデバッグ機能を使って動作を確認すると、「hboot」が格納されているブロックから検索を始めていることが分かりました。TP(V)形式のディレクトリではないし、そもそも何故「hboot」がテープに置かれているのか分かりません。 
  3. テープ上の場所が分かったら、それをメモリ番地0からロードして、制御を渡します。ただしロードする前に、メモリを全て0クリアしています。未初期化の変数を参照してしまった場合、再現不能なバグが出ないための事前準備でしょうか。

 

テープファイル「Unix-v6-Ken-Wellsch.tap」を解析すると、次のようになっていました。

  1. Block#0は、a.out形式の「mboot」が格納されている。
  2. Block#1は、a.out形式の「hboot」が格納されている。
  3. Block#2からは、TP(V)形式のディレクトリ情報が格納されている。格納されているプログラムは、次の通りです。
    1. 「dldr」(size:000000344,tape:000031)
    2. 「dtf」(size:000004546,tape:000032)
    3. 「hboot」(size:000000724,tape:000037)
    4. 「hpuboot」(size:000000766,tape:000040)
    5. 「hthp」(size:000000624,tape:000041)
    6. 「htrk」(size:000000554,tape:000042)
    7. 「htrp」(size:000000566,tape:000043)
    8. 「mboot」(size:000000674,tape:000044)
    9. 「mcopy」(size:000000660,tape:000045)
    10. 「mem」(size:000012756,tape:000046)
    11. 「reset」(size:000000024,tape:000061)
    12. 「rkf」(size:000000200,tape:000062)
    13. 「rkuboot」(size:000000716,tape:000063)
    14. 「rpuboot」(size:000000730,tape:000064)
    15. 「tboot」(size:000000626,tape:000065)
    16. 「tcf」(size:000004516,tape:000066)
    17. 「tmhp」(size:000000574,tape:000073)
    18. 「tmrk」(size:000000524,tape:000074)
    19. 「tmrp」(size:000000536,tape:000075)
    20. 「uboot」(size:000001000,tape:000076)

2026-03-19

Unix-v6-Ken-Wellsch.tapの構造

SIMHのPDP11エミュレータを使ってUNIXv6を学ぼうと考えています。同様の志を持つ人たちが、ネットでも書籍でも多くの情報を提供しています。ただしUNIXがインストールされた環境を前提にしていることが多いように見受けられます。カーネルを学ぶには、インストールが済んだことを前提にする方が良いのだと思いますが、PDP-11について学ぶ練習のため、「SETTING UP UNIX - Sixth Edition」の手順でインストールするところから調べてみようと思います。

 

 SIMHで利用できるテープイメージのファイルが「Unix-v6-Ken-Wellsch.tap」として入手できます。これはSIMHで扱える形式になっているようです。その構造は「SIMH Magtape Representation and Handling」という資料があります。この構造を確認するため、Pythonでスクリプトを組んでみました。

#!/usr/bin/python3

def readblock(f):
    global TapeMark
    global Block
    Block += 1
    len0 = int.from_bytes(f.read(4),'little')
    if len0 == 0:
        TapeMark += 1
        if TapeMark >= 2: raise EOFError
        return 0
    TapeMark = 0
    data = f.read(len0)
    len1 = int.from_bytes(f.read(4),'little')
    print("[%6d]:" % Block, TapeMark, len0, data[:4])
    return 0 if len0 != len1 else len0

TapeMark = 0
Block = 0

with open("Unix-v6-Ken-Wellsch.tap","rb") as f:
    while True:
        try:
            readblock(f)
        except EOFError:
            break
#[EOF]

 これで確認すると、512バイトのブロックが12,100あります。ドキュメントに書かれているとおりです。

 

また先頭ブロックには「mboot」があります。次のブロックには「hboot」が置かれています。その後には「TP(V)」形式のディレクトリが続きます。ブートプログラムとして「mboot」と「hboot」の二つが用意されている理由はなんでしょうか。ドキュメントでは、フロントパネルから入力する「TU16」のプログラムが「(To be added)」となっています。このテープの配布を受けた側がTU10でもTU16でも対応できるようにしておいたのかもしれません。

2026-03-16

SDカードは劣化すると「書込み禁止状態」に入るらしい

スマホで写真を撮影しても、撮ったはずの写真が残っていない現象に遭遇しました。「カシャ」という音はするのですが、ファイルが残っていません。アプリの設定を確認すると「SDカードに記録する」という項目があり、「ON」になっていたので、「OFF」に切り替えたところ、問題が解決したようです。

 

スマホで使っているSDカードは、随分前にガラケーで使っていたものです。15年以上前に購入したものだと思います。劣化していてもおかしくはありませんが、記録されている情報は普通に読み取れるのです。最近は、Googleで似たような事例を検索してみるのではなく、Geminiに相談することが増えました。Geminiが言うには、SDカードが劣化して「書込み禁止状態」になっているのではないかとのことです。

 

SDカードが劣化すると「書込み禁止状態」にはいるという事を初めて知りました。Googleで検索してみたら、そういう状況を報告する「SDカードの「書き換え寿命」と、壊れる直前のサイレントサイン 」が見つかりました。壊れるものは仕方がないので、新しいSDカードを購入するしかありません。劣化したSDカードからファイルを救い出すことはできそうなので、完全に壊れて読めなくなる前に、新しいものと交換しようと思います。

 

2026-03-14

TU10コードからmbootを経由してtmrkが呼ばれるまで

SETTING UP UNIX - Sixth Edition」の「Making a Disk From Tape」において、手順3で入力されたコードを実行すると、テープからプログラムがロードされます。simhのPDP11エミュレータを使用し、テープイメージとして「Unix-v6-Ken-Wellsch.tap」を使用する場合、このロードされたプログラムは「mboot」だと思われます。これは「run」の中で、以下のようにして作られています。

as tpboot.s tty.s tm.s
strip a.out
ls -l a.out
cp a.out /usr/mdec/mboot 

 

そして手順5において、プロンプト「=」が表示され、「tmrk」を入力するように指示されています。

 

この一連の処理を追いかけているのですが、「tpboot.s」では、プロンプト「=」を出し、「TP(V)」形式のテープから指定されたプログラム(例えば「tmrk」)を読みだして、制御を移しているだけです。 

 

つまり、「Making a Disk From Tap」では、次のような段階を踏んで、テープにあるUNIXv6をディスクにコピーしていることになります。

  1. フロントパネルからTU10コードを入力し、実行する。
  2. テープの先頭ブロックにmbootが入っており、それを実行する。
  3. mbootがプロンプト「=」を出し、コマンド「tmrk」などを入力すると、mbootがテープから探し出し、メモリ上にロードする。
  4. メモリ上にロードされたプログラムが、テープからUNIXv6本体をディスクにコピーする。

 

 処理の流れが見えてきました。これだけわかれば十分とも言えますが、mbootに含まれるtpboot.s、tty.s、tm.sは、PDP-11のアセンブラで書かれていますが、短いので、今後UNIXv6の本体を追いかけていく練習として、ロジックを細部まで見ていこうと思います。

2026-03-09

さぁ、ここからはピッチを調節して、あなたが操縦して着陸してください

Windows11でMicrosoft Flight Simulator 2002が動くようになったので、紹介ビデオの直後のフライトに挑んでいます。操作は、ジョイスティックを所有していないので、全てキーボードでおこないます。このフライトは、ゲーム購入直後におこなうものだと思います。飛行用語も操作方法も全く知らずにおこなうので、滅茶苦茶な操縦をしながら、離陸から着陸までを体験します。これがシミュレータなので事故も怪我もありませんが、いきなり飛び立ち着陸させるなんて、本当の飛行訓練ではありえない状況だと思います。

 

離陸は比較的簡単です。エンジンを全開にしてから機首を上げると、離陸できます。空中では、右旋回や左旋回を体験しますが、教官が代わって操縦してくれます。そこまでは、手取り足取りなのに、着陸だけは、「さぁ、ここからはピッチを調節して、あなたが操縦して着陸してください」と言われてしまいます。

 

このソフトを使う人の中には、操縦に関する知識があり、何をすべきか熟知していることもあるでしょう。しかし私は素人なので、何をしたらよいのか、さっぱりわかりません。着陸操作をしろと命じられたら、じゃぁエンジンを切ればよいのだろうかと考えてしまいますが、それでは墜落してしまうでしょう。ならば機種を下に下げれば良いのかとも思いますが、それでは失速してしまいそうです。要するに、何をしたらよいのかわかりません。それなのに教官は「ピッチを操作し、速度を65ノットに保ち、着陸してください」と簡単に言います。もちろんシミュレータですから、操作が酷くても事故にはつながらないのは、十分に承知していますが、困ってしまうのは確かです。

 

飛行機というものは、XYZ軸に応じて、「ヨー」、「ロール」、「ピッチ」という言い方をするようです。教官の言う「ピッチを調節して」というのは、このことを言っているのだろうかと、つい最近気づきました。混乱するのは、計器類の中にピッチトリムというものがあり、教官はこれを操作しろと言っているんだろうかと誤解するのです。

 

何度か離陸着陸を繰り返しているうちに、だんだんわかってきました。しかし空港の滑走路に着陸できたことは一度もなく、建物や樹々に激突します。しかし機体にも自分自身にも何の怪我もないのが、シミュレータですね。

2026-03-07

mboot

UNIX V6のセットアップをおこなうドキュメント「SETTING UP UNIX - Sixth Edition」によると、配布テープは「The tape contains 12100 512-byte records followed by a single file mark」だそうです。さらにオフセット100から4000レコードが「バイナリ」、その後の4000レコードが「ソース」、その後の4000レコードが「ドキュメント」との事です。全体として12,100レコードということは、オフセット0から100レコードには、テープを読みこみディスクに書き出すユーティリティが格納されていることになります。

 

ドキュメントの「Making a Disk From Tape」では、TU10コードにより、テープのオフセット0から数レコードを読んでメモリの000000番地以降に展開しています。ここで何を読み込んだのか不明ですし、どのような処理が行われた結果としてプロンプト「=」が出るのか、霧の中です。もっとも、この過程がわからなくても、UNIX V6のディスクを作ることはできます。しかも、わかったところでUNIX V6の本体の理解が進むわけでもありません。そうであったとしても、何故この処理を理解しようとするのかと言えば、今後UNIX V6を学んでいくための準備練習として最適ではないかと考えるからです。

 

TU10コードを実行した後からプロンプト「=」が出るまでの間を理解するため、Googleを検索したり、Geminiに相談したりしましたが、確たる情報は得られませんでした。そうならば、発想を変えて、TU10コードが実行された後のメモリがどうなっているかを調べてみようと思い至りました。「Installing UNIX v6 (PDP-11) on SIMH」で使われている「Unix-v6-Ken-Wellsch.tap」を使用してTU10コードを実行してみました。その後simhのPDP11エミュレータで「e -m 000000-001000」することで、1レコード分を逆アセンブルしてみました。その内容を確認してみると「mboot」であることが確認できました。

 

UNIX V6のソースを確認すると「source/mdec/run」には、次のような箇所があります。

as tpboot.s tty.s tm.s

strip a.out

ls -l a.out

cp a.out /usr/mdec/mboot 


ソースには「source/mdec/tpboot.s」、「tty.s」や「tm.s」もありますから、逆アセンブルした結果を全て確認したら、まさに「tpboot.s」、「tty.s」、「tm.s」そのものでした。これらをアセンブルしたものが「mboot」というバイナリで、これはa.out形式です。サイズは440バイトだったので、1レコードに収まります。ここから考えても、TU10コードでは数レコードを読み込もうとしていますが、1レコードを読み込むだけで十分であることが分かります。

 

次はmbootの処理を追いかけてみようと思います。 

 

 

 

 

UNIX V6の配布テープを読み込む処理

UNIX V6を通してOSについて深く学ぼうと考えています。simhのPDP-11エミュレータを使用しようと考えています。このようなアプローチは、以前よりオンラインでも書籍でも多くの情報があります。それらは、ほとんどの場合において、UNIX V6がディスク上にインストールされていることを前提としています。しかし「SETTING UP UNIX - Sixth Edition」を読むと、前段階として「Making a Disk From Tape」が必要です。これらはOSの挙動とは関係ありませんが、PDP-11の動作を学ぶには格好の素材ではないかと思います。そういうつもりで、この処理を詳しく調べてみることにしました。

 

まず最初におこなうのは、TU10コードを(本物のPDP-11/40なら、フロントパネルから)入力し、テープから「何か」を読み込むことです。ドキュメントにはバイナリコードが記載されていますが、理解しやすくするため逆アセンブルしておきます。これが100000番地から格納されることになります。

100000: MOV #172526,R0

100004: MOV R0,-(R0)

100006: MOV #060003,-(R0)

100012: BR 100012 

 

100000番地で、R0に定数「172526」を代入しています。これは100004番地の処理をするための、準備と言えます。100004番地では、代入先が「-(R0)」となっていますから、まずR0をデクリメントし、そのR0が指しているアドレスに何かを(ここではR0の内容)を代入しています。R0は172526だったのですから、デクリメントすると172524になります。これはTM11のMTBRCレジスタです。代入される値もR0ですから「172524」です。

 

ドキュメント「TM11 DECmagtape system」(DEC-11-HTMAA-D-D)によると、「4.2.3 Byte Record Counter (MTBRC)」で説明されていますが、転送量の2の補数を指定します。ここでは「172524」を指定していますが、これは転送量を2の補数にしたものなので、本当の転送量は、逆算して、「2732」となります。読み取り操作では、ワード数で指定するようです。テープは512バイトを1レコードとしていますが、2732ワードならば、10レコード以上あるし、しかも中途半端です。何故中途半端な値を指定するのかは不明ですが、推測するに、フロントパネルから入力するロジックを短くしたかったのでしょう。おそらく本当に必要なのは1レコードだったと思われますが、それを忠実にロジックに落とすと、ちょっとだけ長くなるので、それを避けたかったのでしょう。今日であれば気にするほどのことではないと思いますが、当時の時代背景を踏まえると、重大問題だったのだと思います。

 

100006番地では、さらにR0をデクリメントしていますから、172522であるMTCに「060003」を代入しています。これもドキュメントの「4.2.2 Command Register (MTC)」より、「DEN8」が「1」で「DEN5」も「1」なので「800bpiの9チャンネルテープ」であり、「Function」が「001」なので「Read」となり、「GO」が「1」なので実行開始されます。

 

最後に無限ループに入りますが、現実のPDP-11/40ならば、操作する人が目視していれば、テープ装置の読取り終了が判断できるのでしょう。 

 

このようにしてテープから読み込まれた内容(おそらく1レコードで十分なはず)が000000番地から書き込まれています。ドキュメントでは、手順4として「Halt and restart the CPU at 0.」と書かれているので、読み込まれたプログラムに制御が移ります。 

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命令の挙動が理解できない事を学びました。

洗濯時間はこれほど短かったのか

先月、自宅で使用している洗濯機がエラーを出しました。「ピーピーピー」という警告音が鳴った後、操作パネルのLEDが全て点滅していました。その時は、再スタートしたところ、その後は問題ありませんでした。ところが、後日洗濯機を使おうとした際にも、エラーが出てることが多くなりました。もしかしたら故障したのだろうか、買い替えるべきなのかと悩みました。

 

そもそも使用している洗濯機は、製造元が三洋電機です。購入時期は覚えていませんが、20年以上前だと思います。買い替えても良いとは思いますが、自宅で他にも故障が相次いでおり、出費がかさんでいるので、できれば買換えは避けたいところです。

 

何が悪いかわかりませんが、少なくともエラーを出す前から注水の勢いが弱いとは思っていました。水道栓と洗濯機の間が狭くて、ホースが捻じ曲がって配置されています。もしかすると水の通りが悪いのではないかと当たりをつけました。ホースを取り外し、スムースに水が供給されるように、配線を変えてみました。

 

変更した結果、力強く給水されるのが確認され、それ以来エラーも出ていません。これが原因だったのかもしれません。それだけではなく、洗濯時間も短くなりました。以前は2時間くらいかかっていましたが、洗濯量にもよりますが、今は30分ほどで終わります。あまりにも早いので、途中でエラーで止まっているんじゃないかと不安になるくらいです。