蒼天在眼 (そうてんまなこにあり)ーベランダで星を見る

昔、昔、天文少年でした。そして、今は、ベランダから、星を見ています。
いろいろの忘備録

PiDP-11を使う その15 5匹のカタツムリ サブルーチン版の巻

2024-02-08 17:29:02 | コンピュータ

ここまで来ると、プログラムを開発する準備が出来ましたが、なぜ、21世紀の今、PDP-11のような古いコンピュータを知ることが大切か、少し考えてみました。

現在の主流は、X86アーキテクチャの流れを引くINTEL CORE  シリーズだと思われます。AMDの互換プロセッサもこの範疇に含まれるます。元をたどれば、インテルの8086マイクロプロセッサの命令に、その時々の必要性に応じる形で、拡張に拡張を重ねて、古い温泉旅館の新館、別館、別棟の大浴場のような初見では、何が、どこにあってどのように使うのか大変見通しの悪い構造になってしまいました。新たに、コンピュータアーキテクチャを学ぶ人は、どこから手をつければ良いのか、なぜこうなっているのか、迷える仔羊のようになっているのではないでしょうか。本当に同情いたします。

以前に紹介した竹内郁郎さんのブログにこのような一節がありました。長くなりますが引用してみます。(竹内さんは、LISPという人口知能関係の言語の専門家です)

「2010年に東大を定年退職したあと、ヒマになったので、そのへんに転がっているIntelマシンをLispマシンにできないかなと思い、IntelのWebページからIntel 64およびIA-32アーキテクチャの膨大なマニュアルをダウンロードしてみた。Intelマシンでも機械語の重箱の隅をつつけば、Lispマシン風に仕立てることができるかもしれないと考えたからだ。最悪でも、それまで独自マシンのために書いていたマイクロコード(第13回写真2参照)を「なんらか」の形で移植すればいい。だが、マニュアルがなんと総計4,716ページ。いくら読まなくてもいい部分が多いとはいえ、ちょっとめげてしまった。でも、過去のしがらみを一杯背負っていて、まぁ、大変な、かつ使いにくそうなアーキテクチャだということまではわかった。」

Balconも、まったく同感です。度々引用している木村泉先生も講義で、インテルアーキテクチャを採用するという苦渋の選択をした背景についてこのように書いています。

 

インテル8086のことを品劣れるとか、PDP-11の不祥の子孫とか書いています。(苦笑)

これに対して、PDP -11のことは、「実に美しい計算機で、講義するのがとても楽しかった。」(同感)

Balconを含めて、PDP-11のことを覚えている人々の偽らざる感想ではあると思います。インテルのX86アーキテクチャを知る上でも、その先祖のPDP-11を知ることは、役にたつとは言い過ぎでしょうか。

では、表題の5匹のカタツムリのサブルーチン版にかかりましょう。

 プログラムは1000番地から、スタートします。今回は、スタックに帰り番地を積むので、スタック・ポインタをまずセットします。 MOV #1000,SP でスタック・ポインタに1000番地をセットすると、スタックに値が入るたびに、776番地から、774番地、772番地‥‥とスタックが使われていきます。

R1レジスタを繰り返しのカウンタとして、繰り返し回数の5をセットします。

1文字出力するサブルーチンは、R0レジスタの下位1バイトに出力するアスキー・コードを入れると、テレタイプ(TTY)に出力する1文字出力すると言う設計にします。

サブルーチンから戻ると、R1レジスタの値を一つ減らして、結果が0でなければ、1014番地に飛んで、ループします。

5回ループをまわると終了します。

サブルーチンの方は、TTYの状態を調べて、出力可能になったら、一文字書き込んで、RTS PCで、戻ります。

(紙テープと高速紙テープ紙テープ・リーダ/パンチ装置の巻へつづく)


PiDP−11を使う その14 アドレッシング・モードの続きとサプルーチン・コール

2024-02-08 17:28:40 | コンピュータ

いきなりですが、PDP11のアドレシング・モードの説明のOHPです。PDP−11には八つのアドレアシングモードがあります。すでに、0n、27、37と解説しましたが、今回はもう少し系統的に説明します。いちどに、説明すると少しややこしいかもしれませんが、お付き合いお願いします。

まず、間接モードです。これは、オペランドの指定する場所を、アドレスとして解釈するモードです。オペランドの高位3ビットで、アドレッシングを区別しますが、この一番下位の3ビット目が0を含む場合、すなわち、アドレシング指定が偶数の場合は、直接アドレッシング、奇数の場合(3ビット目が1)が、間接アドレシング・モードです。例えば、オペランドが0n(nは8進数で、0から7のレジスタを指定)の時は、レジスタnの内容が、オペレータの作用対象になります(直接アドレッシング)。1nの場合は、レジスタnの値の指す番地のデータが対象になります。(間接アドレッシング)

命令語の直後にオペランドが続く27、37のアドレッシングも2が直接アドレシング、3が間接アドレシングを表しています。

0nと2nの違いは何かというと、0n、1nの場合は、命令の実行後も、nで表されるレジスタはの内容は不変です。2n、3nの場合は、命令の実行後にレジスタの内容が、原則、2増えます。これは、次々にデータをアクセスする場合に便利です。例えば、配列を逐次処理する場合とか。命令を実行するたびに、レジスターの内容が増加するので、プログラムを短くできますし、プログラムの見通しが良くなります。C言語での  

for(i = 1; i <= 10; i++)

        {…}


のような感じでプログラムを書けて便利です。

レジスタを自動インクリメント(増やす)するアドレシングがあるならば、自動デクリメント(減らす)アドレシングモードもあるのかと言うと、ございます。これは、4n、5nで指定します。これは次に出てくるスタックというデータ構造の操作に向いています。ここで注意すべきは、2n、3nがデータにアクセスしたあとに増加するのに対して、4n、5nは、データにアクセスする前に、デクリメントするところが違います。

c言語風に書くと

    2n, 3n   は  i++ なのに対して、4n、5n  は  --i 

になります。なんでこんな仕様なのかというと、スタックにつまれたデータを取り扱うのにこの仕様の方が便利なためだと思われます。ちなみに、PDP−11には スタックにレジスタの内容を積むPUSH命令や、スタックからデータを降ろすPOP命令はありません。これらには6番レジスタ(R6)を間接アドレシングで使用します。例えばR0の内容をスタックに積むには、

010056   と書きます。アッセンブラ風に書くと MOV R0, -(SP)

スタックポインタを2減らして、R0のデータを書き込みます。

スタックトップのデータをR0に戻すには

013600 これは アセンプラ風に書くと  、  MOV (SP)+,R0 となります。

このようにして、PUSH、POPなしで、スタック操作が可能になります。 

 

ここまでで、八つのアドレシングモードのうち六つの解説が終わりました。最後のモードは、モードはインデックス・モードの直接モード(6n)と、間接モード(7n)です。これは、指定されたレジスタに命令語の次のアドレスのデータ(x)を加えたものを目的のアドレスにするというモードで、表の操作などに便利です。加えるXは2の補数方式のマイナスの数でも、問題ありません。例えば、二次元の表で、R1に行の先頭の項目の番地があれば、Xに適当な値を入れれば、任意の項目のデータにアクセスできます。R1に、行の先頭データアドレスが入っている時に、 その次の項目のデータを、R0 レジスタに、読み込む命令はアセンブラ風に書くと、

MOV 2(R1),R0

になり、機械語で書くと

016100

00002

になります。

これで、PDP−11の八つのアドレッシング・モードについて、説明しました。八つのレジスターに八つのアドレッシング・モードで、64パターンのアクセス方法が可能です。PDP−11は、豊富なアドレッシング・モードを持っていると良く言われますが 基本のアドレッシング・モードは 4種類に、直接、と間接の2パターンと、8パターンのレジスタ指定の組み合わせですからそんなに複雑ではありません。しかし、これらを使いこなすには、多少の経験が必要になると思います。

 

次に、サブルーチン・コールについて、見ていきましょう。

例えば、テレタイプに一文字出力するような、何回も繰り返して行う操作は、サブルーチンとして、まとめて、メインプログラムから、呼び出す方が、プログラムがコンパクトになります。また、プログラム全体の見通しもよくなります。大抵のCPUには、サブルーチン呼び出しとサブルーチンからの戻るをサポートする機能が装備されています。PDP−11にもJSR命令(Jump to SubRutine)とRTS(ReTurn from Subrutine)という命令があります。

木村泉先生のOHPでは、サブルーチンコールは 4737 、 戻りには 207の機械語を使うように示しています。他のCPUと同じように使うのであれば、全く問題ありません。しかし、ちょっと変わった使い方もできます。

PDP−11にはサブルーチン・コールする場合、リンケージ・レジスタを指定します。細かいことはどうでもいいという方は、以下は読みとばして下さい

実は、4737、207をそれぞれアセンブラ風に書くと、

JSR PC, @#XXXXX

RTS PC

XXXXXはサブルーチンの先頭番地です。

となります。PCとなっている部分が、リンケージ・レジスタの指定となり、必ず、R0からR7のいづれかを指定しなければなりません。

例えば、

1000: 004137

1002: 003000

1004:…………

1000番地に JSR R1,@#3000

に相当する命令が書かれていたとしましょう。この命令に対して、PDP−11は、次のように動作します。

まず、リンケージ・レジスタR1 の内容を スタックに退避します。次にプログラム・カウンタの内容(戻り番地)1004をR1に移動します。そして3000番地の命令を実行します。

では、サブルーチンから戻る場合は、

3050:000201  RTS R1

という命令があってそのサブルーチンから戻るとします。PDP−11の動作は次のようになります。まず、R1の内容を、プログラムカウンタPC: R7に戻します。 次に、スタックから卸したデータをR1 に戻します。プログラムは、リターン命令の直前のR1レジスタの内容のデータの指す番地から再開します。

リンケージ・レジスタに PC; R7以外のレジスタを指定することより、サブルーチン内でリンケージ・レジスタの値を変更して、戻り番地以外の場所に戻ることができます。こんな機能は役に立つのかと疑うのも無理はないと思いますが、連載の後半で、リンケージ・レジスタを使ったサブルーチンの例を解説する予定です。

(5匹のカタツムサブルーチン版の巻へつづく)

 


PiDP-11を使う その13 5匹のカタツムリの巻

2024-02-08 17:26:40 | コンピュータ

いよいよ、プログラムらしいプログラムに進みます。

今回はカタツムリに見立てた@を5つターミナル・テレタイプに出力するプログラムを書いてみます。前回のテレタイプ出力命令に加えて、分岐命令を使ったループを見ていきましょう。

プログラムの構造は次の通りです。

1.繰り返しの回数 5を R0レジスタに入れる。

  010200, 000005

2. テレタイプの 状態レジスタをチェックします。

   132737, 000200,177564

3.テレタイプが出力可能(READY)になると上の命令を実行すると、Zフラグがリセットされます。それまで、ループします。XXは、戻るステップ数(オフセット)です。あとで計算します。

   0017XX、

4.テレタイプに、@のアスキーコード100(8進数)を出力します。

   112737,000100,177566

5.カウンタとして使っているR0を1つ減らします。

   005300

6.R0が0でなければ、2へもどります。YYもオフセット

   0013YY

7.  停止します。

   000000

 

1000番地から、プログラムを格納すると

1000:012700

1002:000005

1004:133237

1006:000200

1010:177564

1012:0017XX

1014:112737

1016:000100

1020:177566

1022:005300

1024:0013YY

1026:000000

まず、XXを決めます。 分岐命令を実行する段階でプログラムカウンタは次の命令の番地を指しています。つまり1014です、ここから数えて4ステップ戻ります。−4ば74なのでXXは74になります。 ああややこしい。こんな表を作っておくと便利です。この表はブランチ命令の次から数えなくてもいいようにわざとずらしてあるので、ブランチ命令から、何語移動するかを数えればいいように作っています。この場合前にBEQ命令から今度は3語戻るので、中央の3の列の前へ飛ぶの欄を74を使うことになります。

つぎにYYを決めます。8語分戻ることになります。表で8語のところを見ると67が見つかります。XXを74,YYを67として、プログラムを完成させるとこんな感じになります。

実際にPiDP−11にプログラムを入力して実行するとこのようになります。

simhは、-m、スイッチを付けると、ニーモニックで出力できます。最近知りました。

(アドレッシング・モードの続きとサブルーチン・コールの巻につづく)

 


PVバーナー

PVアクセスランキング にほんブログ村