Burroughs Large Systems Group は、スタックマシン命令セットと高密度シラブルを使用した、大型48 ビットメインフレームのファミリーを製造しました。[ NB 1 ]このファミリーの最初のマシンは 1961 年に登場した B5000 で、シングルパス コンパイラを使用してALGOL 60プログラムのコンパイルに非常に最適化されていました。B5000 は、B5500 (ドラムではなくディスク) および B5700 (クラスタとして動作する最大 4 台のシステム) に進化しました。その後の主要な再設計には、B6500/B6700 シリーズとその後継機、および独立した B8500 シリーズが含まれます。
1970年代、バローズ社は、ハイエンド、ミッドレンジ、エントリーレベルのビジネスコンピュータシステム向けに、それぞれ大きく異なる製品ラインアーキテクチャを持つ3つの部門に組織されていました。各部門の製品ラインは、特定のプログラミング言語に合わせてコンピュータの命令セットを最適化するという異なるコンセプトに基づいて開発されました。「バローズ・ラージシステムズ」とは、COBOLに最適化されたミディアムシステムズ(B2000、B3000、B4000)や、柔軟なアーキテクチャを持つスモールシステムズ(B1000)とは対照的に、これらの大規模システム製品ラインすべてを総称するものでした。
1880年代に設立されたバローズ社は、コンピューター業界で最も長く継続的に事業を営んできた企業でした(エリオット・ブラザーズ社はバローズ社より先に設立されましたが、19世紀にはコンピューター機器を製造していませんでした)。1950年代後半になっても、同社のコンピューター機器はセンシマティックのような電気機械式会計機に限られていました。より大規模なコンピューターの製造を開始した従来のライバルであるIBMやNCR 、あるいは最近設立されたユニバック社と競合できるものは何もありませんでした。1956年、同社はエレクトロデータ社を買収し、その設計をB205としてブランド名を変更しました。
Burroughs が最初に社内で開発したマシンである B5000 は 1961 年に設計され、Burroughs は当時入手可能な最先端のコンピューティングのアイデアに基づいたまったく異なる設計の戦略で、市場への後発の参入に対処しようとしました。B5000 アーキテクチャは廃止されましたが、B6500 (およびその後の B6700 と B7700) に影響を与えました。このアーキテクチャを使用するコンピュータは、 B6700 で最初に導入されたMCPオペレーティングシステムの進化版で互換性のあるバージョンを実行する Unisys ClearPath Libra サーバーとしてまだ生産されています。3 番目で最大のラインである B8500 [ 1 ] [ 2 ]は商業的に成功しませんでした。Unisys は独自のCMOSプロセッサ設計に加えてIntel Xeonプロセッサも使用し、 Libra サーバーでMCP、Microsoft Windows、Linuxオペレーティングシステムを実行します。カスタム チップの使用は徐々に廃止され、2018 年までに Libra サーバーは数年間完全に汎用 Intel になりました。
最初のシリーズの最初のメンバーである B5000 [ 3 ]は、1961 年にRobert (Bob) Bartonのリーダーシップの下、チームによって設計が開始されました。これは珍しいアーキテクチャを持っていました。コンピュータ科学者のJohn Masheyは、これを最も賞賛するアーキテクチャの 1 つです。「私はいつも、これは私が見た中で最も革新的なハードウェア/ソフトウェアの組み合わせ設計の 1 つですであり、時代をはるかに先取りしていると思っていました。」[ 4 ] B5000 の後継機は、ドラムストレージではなくディスクを使用する B5500 [ 5 ]と、共有ディスクの周りに複数の CPU をクラスタリングできる B5700 でした。B5700 の後継機はありませんでしたが、B5000 ラインは B6500 の設計に大きな影響を与え、Burroughs はMaster Control Program ( MCP ) をそのマシンに移植しました。
B5000は、当時としては珍しく、アーキテクチャと命令セットがソフトウェアのニーズを考慮して設計されていた。これは、プロセッサとその命令セットを設計してからソフトウェア開発担当者に引き渡すという、当時のコンピュータシステム設計の常識から大きく逸脱したものであった。
ワードモードのB5000、B5500、B5700には、メインプログラム(SALFオフ)を実行しているかサブルーチン(SALFオン)を実行しているかに応じて、2つの異なるアドレッシングモードがあります。メインプログラムの場合、オペランド呼び出しまたはディスクリプタ呼び出しのTフィールドは、プログラム参照テーブル(PRT)を基準としています。サブルーチンの場合、アドレッシングの種類は、Tの上位3ビットとマークスタックフリップフロップ(MSFF)に依存します。詳細は、「B5x00相対アドレッシング」を参照してください。
B5000は、高級言語のみをサポートするように設計されました。当時、高級言語はFORTRAN、そしてCOBOLによってようやく注目を集め始めたばかりでした。FORTRANとCOBOLは、現代のソフトウェア技術においては劣った言語だと考える人もいたため、より新しく、ほとんど試されていない言語であるALGOL-60が採用されました。B5000用に選ばれたALGOLの方言はElliott ALGOLで、これはCAR HoareがElliott 503上で最初に設計・実装したものです。これは、ALGOLが無視していたI/O命令と強力な文字列処理命令を備えた、ALGOLの実用的な拡張でした。Hoareの有名なチューリング賞受賞講演はこのテーマに関するものでした。
このように、B5000は非常に強力な言語を基盤としていた。ドナルド・クヌースは、夏休み中の3ヶ月間に、以前のバローズ社のマシンにALGOL 58を実装しており、コンサルタントとしてB5000の設計にも間接的に関わっていた。多くの人々は、高水準言語はアセンブラと同じパワーを持つことはできないと誤解し、ALGOLをシステムプログラミング言語としての可能性を見過ごしていた。
バローズ社のALGOLコンパイラは非常に高速でした。オランダの科学者エドガー・ダイクストラは、パサデナのB5000工場でコンパイルするプログラムを提出した際、その速さに感銘を受けました。彼のカードデッキはほぼ瞬時にコンパイルされ、彼はすぐにオランダのアイントホーフェン工科大学に数台のマシンを導入したいと考えました。コンパイラが高速だった理由はいくつかありますが、主な理由はワンパスコンパイラだったことです。初期のコンピュータはソースコードを格納するのに十分なメモリがなかったため、コンパイラ(アセンブラでさえも)は通常、ソースコードを複数回読み込む必要がありました。バローズ社のALGOL構文は、公式言語とは異なり、各変数(またはその他のオブジェクト)を使用する前に宣言する必要があるため、データを一度だけ読み込むALGOLコンパイラを作成することが可能です。この概念は理論的に深い意味を持ちますが、非常に高速なコンパイルも可能にします。バローズ社の大型システムは、パンチカードからソースコードを読み込む速度と同じ速さでコンパイルでき、業界最速のカードリーダーを備えていました。
強力なBurroughs COBOLコンパイラは、ワンパスコンパイラであり、処理速度も非常に高速でした。4000枚のカードからなるCOBOLプログラムは、1分間に1000枚のカードを読み取るリーダーがコードを読み取る速度とほぼ同じ速さでコンパイルされました。カードがリーダーを通過するとすぐに、プログラムは使用可能な状態になりました。

B6500 [ 7 ](1969年納入[ 8 ] [ 9 ])とB7500は、現在まで残っている唯一のBurroughsシステム系列の最初のコンピュータでした。これらはB5000に影響を受けていましたが、全く新しいアーキテクチャを持っていました。最も重要な違いは、
B6700とB7700の顧客の中には、1971年のニュージーランドの5つの大学すべてが含まれていた。[ 11 ]
ILLIAC IVスーパーコンピュータは、B6500を「I/O制御コンピュータ」として使用し、ILLIAC IVの監視機能を実行したり、ILLIAC IVメモリとの間でI/O操作を設定および開始したりした。[ 12 ]
B8500 [ 1 ] [ 2 ]シリーズは、B5000 に影響を受けた軍用コンピュータである D825 [ 13 ]から派生したものです。
B8500は、1960年代にB5500とD825の設計を統合する試みとして設計されました。このシステムは、磁気薄膜メモリを備えたモノリシック集積回路を使用していました。アーキテクチャは、B5500と同様に48ビットのワード、スタック、およびディスクリプタを採用していましたが、上位互換性があると宣伝されていませんでした。[ 1 ] B8500は安定して動作させることができず、完成したシステムを提供することなく、1970年以降にプロジェクトは中止されました。[ 2 ]
仮想メモリの中心概念は、1950年代後半のフェランティ・アトラスとライス研究所コンピュータの設計に現れ、記述子とタグ付きアーキテクチャの中心概念はライス研究所コンピュータの設計に現れた[ 14 ]。しかし、これらの設計がバローズに直接的な影響を与えたとしても、B5000、B6500、B8500のアーキテクチャはアトラスやライスマシンのものとは非常に異なっており、また、互いにも非常に異なっている。
Burroughs の大型システムの最初のものは B5000 でした。1961 年に設計されたこのコンピュータは、ディスクリート トランジスタロジックと磁気コア メモリを使用した第 2 世代のコンピュータで、その後 B5500 と B5700 が続きました。B5000 アーキテクチャを置き換える最初のマシンは B6500 と B7500 でした。B6500 と B7500 の後継機は、ハードウェア開発のトレンドに従って、次の 25 年間にわたって新しいロジックでアーキテクチャを再実装し、B6500、B7500、B6700、B7700、B6800、B7800、B5900、[ NB 4 ] B7900、そして最後に Burroughs A シリーズが登場しました。Burroughs がSperry Corporationを買収してUnisysに社名を変更した合併後、同社は MCP CMOS ASICをベースにした新しいマシンの開発を続けました。これらのマシンはLibra 100からLibra 500までで、Libra 590は2005年に発表されました。Libra 590を含む後継機種は、Intel Xeonプロセッサを搭載し、MCP CMOSプロセッサ上だけでなく、エミュレーション環境でもBurroughsの大規模システムアーキテクチャを実行できます。Unisysが今後も新しいMCP CMOS ASICの開発を続けるかどうかは不明です。
ハードウェアとソフトウェアの設計、開発、製造は、カリフォルニア州オレンジ郡とフィラデルフィア郊外の2つの主要拠点に分かれて行われました。B5000とB5500を開発した最初の大型システム工場はカリフォルニア州パサデナにありましたが、B6500の開発のためカリフォルニア州シティ・オブ・インダストリーに移転しました。カリフォルニア州ミッションビエホの工場を拠点とし、近隣のアーバインやレイクフォレストの施設も含むオレンジ郡の拠点は、より小型のB6x00シリーズを担当し、ペンシルベニア州トレディフリンを拠点とする東海岸の拠点は、より大型のB7x00シリーズを担当しました。両シリーズのすべてのマシンは完全なオブジェクト互換性があり、一方のマシンでコンパイルされたプログラムはもう一方のマシンで実行できました。より新しく大型のモデルには、より古く低速なモデルではサポートされていない命令がありましたが、ハードウェアは認識されない命令に遭遇すると、それを解釈するオペレーティングシステムの機能を呼び出しました。その他の違いとしては、プロセス切り替えとI/Oの処理方法、保守機能とコールドスタート機能などがあります。より大規模なシステムには、ハードウェアによるプロセススケジューリング機能、より高性能な入出力モジュール、そしてより高機能な保守プロセッサが搭載されていました。Bxx00シリーズがAシリーズに置き換えられた際、これらの違いは維持されましたが、型番だけでは容易に識別できなくなりました。
Burroughs社の大型システムは、ALGOL由来のスタックアーキテクチャを採用している。B5000は、スタックベースのシステムとしては最初のものであった。
B5000はALGOLをサポートするために特別に設計されましたが、これはあくまで出発点に過ぎませんでした。COBOLなどの他のビジネス向け言語も十分にサポートされており、特に高速コンパイラの開発のために組み込まれた強力な文字列演算子が大きな役割を果たしました。
B5000で使用されているALGOLは、ALGOLの拡張サブセットです。強力な文字列操作命令が含まれていますが、未指定の仮引数など、特定のALGOL構造は除外されています。DEFINEメカニズムは、C言語の#defineと同様の目的を果たしますが、プリプロセッサではなく言語に完全に統合されています。EVENTデータ型はプロセス間の連携を容易にし、ON FAULTブロックはプログラムの障害処理を可能にします。
ALGOLのユーザーレベルには、オペレーティングシステムやその他のシステムソフトウェアに必要な、セキュリティ上のリスクを伴う構造の多くが含まれていません。これらの追加構造は、2つのレベルの言語拡張機能によって提供されます。1つはMCPおよび関連ソフトウェアを作成するためのESPOLとNEWP、もう1つは特定の種類のシステムソフトウェア向けに、より具体的な拡張機能を提供するDCALGOLとDMALGOLです。
元々、B5000 MCP オペレーティングシステムは、拡張 ALGOL の拡張であるESPOL ( Executive Systems Programming Oriented Language ) で記述されていました。このALGOL 60の上位互換言語は、後にシステムプログラミング言語[ 24 ]またはマシン指向高階言語(mohol) と呼ばれる機能を提供し、マルチプロセッシングシステム ( Burroughs の大型システムはマルチプロセッサシステムでした) でプロセッサを割り込みます。ESPOL は、Burroughs のコンピュータシステム (B5000 から B6700) でマスター制御プログラム(MCP)を記述するために使用されました。 [ 25 ] [ 26 ] [ 27 ] ESPOL のシングルパスコンパイラは、毎秒 250 行以上をコンパイルできました。
これは70年代半ばから後半にかけてNEWPと呼ばれる言語に置き換えられました。NEWPはおそらく「新しいプログラミング言語」の略だったと思われますが、その名前には様々な逸話があります。当時バロウズ社内でよく聞かれた(おそらく作り話の)話では、「役員用トイレ使用権なし」から来ていると言われています。別の話では、1976年頃、バロウズ社のジョン・マクリントック(NEWPを開発していたソフトウェアエンジニア)が、またもや「まだ名前はついていないのか」と聞かれ、「にゃーーー」と答えて、その名前を採用したとされています。NEWPもALGOLのサブセット拡張でしたが、ESPOLよりも安全性が高く、ALGOLのあまり使われていない複雑な部分をいくつか削除していました。実際、NEWPコンパイラは、ブロックがそれらの命令を許可するように明示的にマークされていない限り、すべての安全でない構造を拒否します。このようなブロックのマーク付けは、多層的な保護メカニズムを提供します。
NEWP プログラムは、安全でない構造を含む場合、最初は実行できません。システムのセキュリティ管理者は、そのようなプログラムを「承認」して実行可能にすることができますが、一般ユーザーはこれを行うことができません。(通常は実質的にルート権限を持つ「特権ユーザー」でさえ、サイトが選択した構成によってはこれを行うことができない場合があります。)NEWP は汎用プログラムの作成に使用でき、大規模ソフトウェアプロジェクト向けに設計された多くの機能を備えていますが、ALGOL のすべての機能をサポートしているわけではありません。
NEWPには、オペレーティングシステムなどの大規模ソフトウェアプロジェクトを実現するための様々な機能が備わっています。これには、名前付きインターフェース(関数とデータ)、インターフェースのグループ、モジュール、スーパーモジュールなどが含まれます。モジュールはデータと関数をグループ化し、モジュール内でグローバルなデータへの容易なアクセスを可能にします。インターフェースを使用すると、モジュールは関数とデータをインポートおよびエクスポートできます。スーパーモジュールを使用すると、モジュールをグループ化できます。
当初の実装では、システムは専用のデータ通信プロセッサ(DCP)を接続して、リモートデバイスとの間でメッセージの入出力処理を行っていました。これは、従来のレジスタアーキテクチャとハードウェアI/O機能を備えた24ビットのミニコンピュータで、数千台のリモート端末を処理できました。DCPとB6500はメモリ内のメッセージ(現代の用語で言えばパケット)で通信し、MCSがB6500側でこれらのメッセージの処理を行いました。初期の頃、DCPにはアセンブラ(Dacoma)と、B6500 ALGOLで記述されたDCPProgenというアプリケーションプログラムがありました。その後、NDL(Network Definition Language)コンパイラがDCPコードとNDF(ネットワーク定義ファイル)を生成しました。最終的に、さらなるアップデートにより、モデル4および5のDCPと連携して使用されるNDLII言語とコンパイラが開発されました。DCP命令の種類ごとに1つのALGOL関数があり、その関数を呼び出すと、対応するDCP命令ビットが出力されました。 DCPプログラムは、これらの関数への呼び出しが長いリストで構成されたALGOLプログラムであり、各アセンブリ言語ステートメントごとに1つの関数が呼び出されていました。基本的に、ALGOLはマクロアセンブラのマクロパスのように機能しました。最初のパスはALGOLコンパイラであり、2番目のパスは生成されたプログラム(B6500上で実行)であり、これによりDCP用のバイナリが出力されました。
1980年代初頭から、DCP技術はICP(Integrated Communications Processor)に置き換えられ、メインフレームシステムにLANベースの接続機能を提供するようになりました。リモートデバイス、およびリモートサーバー/メインフレームは、CP2000と呼ばれる独立型デバイスを介してネットワークに接続されました。CP2000は、BNAV2(Burroughs Network Architecture Version 2)ネットワーク技術を使用してノードが接続される分散ネットワークでネットワークノードをサポートするように設計されていました。BNAV2は、IBM SNA製品のBurroughs版であり、PUT2およびPUT5トランスポートモードの両方でIBM環境との相互運用をサポートしていました。外部データ通信ハードウェアの変更は、既存のMCS(Message Control System(後述))ソフトウェアの変更を必要としませんでした。
入力時には、メッセージは内部バスを介してDCPから関連するMCPデータ通信制御(DCC)DCPプロセススタックに渡されました。システムに設定されているDCPごとに1つのDCCプロセスが起動されました。DCPプロセススタックは、受信メッセージが特定の送信元デバイスからのトラフィックを処理するように指定されたMCSに配信されるようにキューに入れ、応答があればDCPに返して宛先デバイスに配信するようにしました。処理の観点からは、5種類のDCP、ICP、またはICP/CP2000の組み合わせなど、異なるタイプのゲートウェイハードウェアを処理するためにMCSソフトウェアに変更を加える必要はありませんでした。
MCSはメッセージ配信サービスであるだけでなく、オペレーティングシステムコード(NEWP)とユーザープログラム(ALGOL、またはCOBOL、FORTRAN、後期にはJAVAなどの他のアプリケーション言語)の間のセキュリティの中間レベルでもあります。MCSはミドルウェアプログラムとみなすことができ、DCALGOL(データ通信ALGOL)で記述されます。前述のように、MCSはデータ通信制御スタック(DCC)によって管理されるキューからメッセージを受信し、これらのメッセージを処理のために適切なアプリケーション/機能に転送します。初期のMCSの1つはCANDE(Command AND Edit)で、オンラインプログラム開発環境として開発されました。ニュージーランドのオタゴ大学は、IBMがIBM 360シリーズシステム上で動作するCALL/360として知られるリモートタイムシェアリング/プログラム開発サービスを提供していたのと同時期に、CANDEと同等の軽量プログラム開発環境であるSCREAM/6700を開発しました。COMSという別のMCSは1984年頃に導入され、高性能トランザクション処理制御システムとして開発されました。 GEMCOS(汎用メッセージ制御システム)や、オーストラリアのBurroughsの子会社が開発したTPMCS(トランザクション処理MCS)など、前身となるトランザクション処理環境が存在した。これらのトランザクション処理MCSは、アプリケーションデータをオンラインの本番環境に配信し、リモートのユーザー、デバイス、システムに応答を返す機能をサポートしていた。
MCSは注目すべきソフトウェアです。ユーザーセッションを制御し、ユーザーごとのプロセスを実行することなくユーザーの状態を追跡できます。これは、単一のMCSスタックを複数のユーザーが共有できるためです。負荷分散もMCSレベルで実現できます。たとえば、スタックごとに30人のユーザーを処理したい場合、ユーザーが31人から60人の場合は2つのスタック、61人から90人の場合は3つのスタック、といった具合になります。これにより、B5000マシンはサーバーにおいて大きなパフォーマンス上の利点を得られます。ユーザーがシステムに接続するたびに別のユーザープロセスを起動して新しいスタックを作成する必要がないためです。このように、MCSを使用することで、ユーザーが状態を必要とするかどうかにかかわらず、効率的にユーザーにサービスを提供できます。MCSは、大規模なトランザクション処理の基盤も提供します。
1988年頃、主に米国政府機関向けに、CP2000分散通信プロセッサをプロトコルホストとして利用するTCP/IPの実装が開発されました。2~3年後、このTCP/IP実装はホスト/サーバ方式に書き換えられ、パフォーマンスと機能が大幅に向上しました。ほぼ同時期に、主にCP2000上でOSIプロトコルスタックの実装が行われましたが、メインシステムには大規模なサポートインフラストラクチャが実装されました。X.400メールホスティングやX.500ディレクトリサービスなど、OSI標準で定義されたすべてのアプリケーションが実装されました。
ALGOL の別の派生版として、DMALGOL (データ管理 ALGOL) があります。DMALGOL は、DASDL (データアクセスおよび構造定義言語) コンパイラによって作成されたデータベース記述ファイルから DMSII データベース ソフトウェアをコンパイルするために ALGOL を拡張したものです。データベース設計者と管理者は、データベース記述をコンパイルして、指定されたテーブルとインデックスに合わせた DMALGOL コードを生成します。管理者は DMALGOL を自分で記述する必要はありません。通常のユーザー レベルのプログラムは、主に ALGOL と COBOL などのアプリケーション言語で記述されたコードにデータベース命令とトランザクション処理ディレクティブを追加することで、データベースへのアクセスを取得します。DMALGOL の最も注目すべき機能は、テーブルとインデックスを処理するためのコードを生成するプリプロセッシング メカニズムです。
DMALGOLのプリプロセッシングには変数とループが含まれており、コンパイル時変数に基づいて名前を生成できます。これにより、ループを持たないプリプロセッシング機能では不可能な、はるかに高度なカスタマイズが可能になります。
DMALGOLは、 DMSIIデータベース向けにカスタマイズされたアクセスルーチンを提供するために使用されます。データベースはデータアクセスおよび構造定義言語(DASDL)を使用して定義され、その後、プリプロセッサによってスキーマがカスタマイズされたDMALGOLアクセスルーチンに変換され、コンパイルされます。つまり、他のDBMS実装とは異なり、実行時にデータベース固有のif/then/elseコードが不要になることがよくあります。1970年代には、この「カスタマイズ」はコード量と実行時間を削減するために広く利用されました。その後、メモリと速度に関する低レベルの微調整の重要性が低下したこと、およびプリプロセッシングをなくすことでコーディングが簡素化され、より重要な最適化が可能になったことなどから、この手法の使用頻度は大幅に減少しました。
アプリケーションプログラムからデータベースにアクセスできるようにするためのALGOLのアプリケーション版はBDMSALGOLと呼ばれ、データベースへのアクセスやレコード操作のための「FIND」、「LOCK」、「STORE」、「GET」、「PUT」などの動詞が含まれています。さらに、複数のプロセスが同じ構造体にアクセスして更新する際に発生するデッドロック状態を解消するために、「BEGINTRANSACTION」と「ENDTRANSACTION」という動詞も実装されています。
バロウズ社のロイ・ガックは、 DMSIIの主要開発者の一人だった。
後年、コンパイラコードのサイズがそれほど問題とならなくなったため、ほとんどのプリプロセッシング構造がALGOLのユーザーレベルで利用可能になった。安全でない構造とデータベース記述ファイルの直接処理のみがDMALGOLに限定されたままとなっている。
初期の多くのシステムや言語では、プログラマーはルーチンを小さくしすぎないようにとよく言われていました。プロシージャ呼び出しと戻りは、スタックを維持するために多くの操作を実行する必要があったため、コストがかかりました。B5000はスタックマシンとして設計されており、配列(文字列やオブジェクトを含む)を除くすべてのプログラムデータはスタック上に保持されました。これは、スタック操作が効率化されるように最適化されていたことを意味します。スタック指向のマシンであるため、プログラマーがアドレス指定できるレジスタはありません。
B5000およびB6500シリーズでは、マルチタスク処理も非常に効率的です。プロセス切り替えを実行するための具体的な手順は以下のとおりです。
各スタックと関連する[ NB 5 ]プログラム参照テーブル(PRT)はプロセス(タスクまたはスレッド)を表し、タスクはリソース要求を待機している間ブロックされる可能性があります(プリエンプティブマルチタスクによってタスクが中断された場合、プロセッサの実行を待機することも含まれます)。ユーザープログラムはIP1、[ NB 5 ] 、 IP2 [ NB 5 ]、またはMVST [ NB 6 ]を発行することはできません。オペレーティングシステム内でこれを行う場所は1つだけです。
プロセス切り替えは、次のような流れで行われます。プロセスが、すぐには利用できないリソースを要求します。たとえば、現在メモリにないブロックからファイルのレコードを読み取る場合や、システムタイマーが割り込みを発生させた場合などです。オペレーティングシステムのコードがユーザースタック上で実行され、ユーザープロセスのタイマーがオフになります。現在のプロセスは、要求されたリソースに対応する適切なキュー、またはプリエンプティブなコンテキストスイッチの場合はプロセッサを待機するレディキューに配置されます。オペレーティングシステムはレディキューの最初のプロセスを決定し、move_stack命令を呼び出します。これにより、レディキューの先頭のプロセスがアクティブになります。
スタックのパフォーマンスは、レジスタベースのアーキテクチャに比べて遅いと考えられていました。たとえば、System/360では、このようなアーキテクチャが検討されましたが、却下されました。[ 29 ]システム速度を向上させる方法の 1 つは、データをプロセッサのできるだけ近くに保持することです。B5000 スタックでは、スタックの最上位 2 つの位置をレジスタ A と B に割り当てることでこれを実現しました。ほとんどの操作は、スタックの最上位の 2 つの位置で実行されます。B5000 以降の高速マシンでは、スタックのより多くの部分がプロセッサ近くのレジスタまたはキャッシュに保持される可能性があります。
そのため、B5000システムの後継機種の設計者は最新の技術を駆使して最適化を行うことができ、プログラマーは高速化のためにコードを調整する必要がなく、再コンパイルすら不要なため、ソフトウェアへの投資を無駄にすることなく運用できます。実際、プロセッサのアップグレードを重ねても長年にわたり動作し続けるプログラムも存在します。このような高速化は、レジスタベースのマシンでは限界があります。
RISC設計者が提唱した速度向上のもう一つのポイントは、すべての回路が単一チップ上に集積されていればプロセッサの速度が大幅に向上するという点でした。これは、B5000のような複雑なアーキテクチャでは単一チップに収まりきらないほどのトランジスタが必要だった1970年代には有効な主張でした。しかし、今日では状況は異なり、B5000の後継機はすべて単一チップ上に集積され、キャッシュや命令パイプラインといった性能向上技術も搭載されています。
実際、B5000の後継機種であるAシリーズには、1980年代後半に登場した初のシングルチップメインフレーム、Micro-Aが含まれていた。この「メインフレーム」チップ(シングルチップAシリーズメインフレームプロセッサの略でSCAMPと命名)は、Intelベースのプラグイン式PCボード上に搭載されていた。
プログラムがスタック構造にどのようにマッピングされるかの例を以下に示します。
始める —— これは語彙レベル2です(レベル0はオペレーティングシステム用に予約されており、レベル1はコードセグメント用に予約されています)。 —— レベル2では、プログラム用のグローバル変数を配置します。 整数i、j、k; 実数f、g; 配列a [0:9]; 手続きp (実数p1 , p2 ); 値p1 ; — p1 は値渡し、p2 は暗黙的に参照渡し。 begin — — — — — — — — — — — — — — — — — — — このブロックは語彙レベル3です — — — — — — — — — — — — — — — — — — real r1 , r2 ; r2 := p1 * 5 ; p2 := r2 ; — これはg をr2 の値に設定しますp1 := r2 ; — これはp1 をr2に設定しますが、f は設定しません —これはp1のf の元の値を上書きするため、 — コーディングミス。そのため、ALGOL の後継者の中には、 — 値パラメータは読み取り専用である場合もあるが、ほとんどはそうではない。 r2 > 10 の場合、開始 —— — ここで宣言された変数により、この語彙レベルは4になります —— 整数n ; — 変数の宣言により、これはブロックとなり、いくつかの処理が実行されます。 — スタック構築コード。通常、ここで変数を宣言することはありません。 — この場合、これはブロックではなく複合ステートメントになります。 ... <== サンプルスタックはここのどこかで実行されています。 終了; 終了; ..... p ( f , g ); end .
各スタックフレームは、現在の実行環境における字句レベルに対応します。ご覧のとおり、字句レベルはプログラムの静的なテキストのネスト構造であり、動的な呼び出しのネスト構造ではありません。シングルパスコンパイラ向けに設計された言語であるALGOLの可視性ルールでは、現在の位置より前に宣言された変数のみがそのコード部分で可視となるため、前方宣言が必要となります。囲んでいるブロック内で宣言されたすべての変数は可視です。もう1つのケースとして、同じ名前の変数が内側のブロック内で宣言される場合があり、その場合、外側の変数は事実上隠蔽され、アクセスできなくなります。
字句ネストは静的であり、再帰などによる実行ネストとは無関係であるため、5 レベル以上深くネストされたプロシージャを見つけることは非常にまれであり、そのようなプログラムは構造的に劣悪であると主張することもできます。B5000 マシンでは、最大 32 レベルまでのネストが可能です。生成方法がプロシージャの中にプロシージャを頻繁にネストする場合、出力として Algol ソース (特定の問題を解決するために調整されたもの) を生成する一部のシステムでは、これが問題を引き起こす可能性があります。
プロシージャは、通常、呼び出し、処理、実行の4つの方法で呼び出すことができます。
通常の呼び出しでは、呼び出し元のルーチンが呼び出されるまで中断されるという、どのプログラミング言語でもルーチンを呼び出す通常の方法でプロシージャが呼び出されます。
呼び出しメカニズムは、プロシージャをコルーチンとして呼び出します。コルーチンは、開始プロセスと同じ字句レベルで独自のスタック内で動作する同期エンティティとして確立されたパートナータスクです。制御は、 CONTINUE命令によって開始プロセスとコルーチン間で明示的に渡されます。
プロセス機構は、処理対象のプロシージャの字句レベルから始まる独立したスタックをセットアップして、プロシージャを非同期タスクとして呼び出します。非同期タスクであるため、コルーチンとは異なり、タスク間で制御が渡される正確なタイミングを制御することはできません。処理対象のプロシージャは、囲んでいる環境にアクセスできるため、これは非常に効率的なプロセス間通信(IPC)メカニズムとなります。2つ以上のタスクが共通変数にアクセスできるようになるため、競合状態を防ぐためにタスクを同期させる必要があります。これは、EVENTデータ型によって処理されます。EVENTデータ型では、プロセスは、他の協力プロセスによって発生するまで、1つ以上のイベントを待機できます。EVENTは、PROCURE関数とLIBERATE関数による相互排他同期も可能にします。何らかの理由で子タスクが終了しても、呼び出し元のタスクは継続できますが、親プロセスが終了すると、すべての子プロセスが自動的に終了します。複数のプロセッサを搭載したマシンでは、プロセスが同時に実行される場合があります。このEVENTメカニズムは、マルチタスクに加えて、マルチプロセッシングの基本的なイネーブラーです。
最後の呼び出しタイプは「実行」です。これはプロシージャを独立したタスクとして実行し、元のプロセスが終了した後も処理を継続できます。そのため、子プロセスは親プロセスの環境内の変数にアクセスできず、呼び出されたプロシージャに渡されるすべてのパラメータは値渡しでなければなりません。
このように、Burroughs Extended ALGOLは、 Adaなどの後発言語に見られるようなマルチプロセッシングや同期機能の一部を備えていた。ハードウェアに組み込まれた非同期処理のサポートを活用していたのである。
最後に考えられるのは、NEWPではプロシージャをINLINEとして宣言することです。つまり、コンパイラがプロシージャへの参照を検出すると、プロシージャ呼び出しのオーバーヘッドを削減するために、プロシージャのコードがインラインで生成されます。これは、小さなコード片に対して行うのが最適です。インライン関数は、 C言語の#defineなどのパラメータ付きマクロに似ていますが、マクロで発生するようなパラメータに関する問題は発生しません。
サンプルプログラムでは通常の呼び出しのみが使用されているため、すべての情報は単一のスタック上に格納されます。非同期呼び出しの場合、各非同期プロセスごとに個別のスタックが初期化されるため、プロセスはデータを共有しながら非同期的に実行されます。
スタックハードウェアの最適化とは、Dレジスタ(または「表示」レジスタ)を提供することです。Dレジスタはソースプログラムのスコープ、つまりソースコード内のネスト構造に対応します。これらのレジスタは、呼び出された各スタックフレームの開始位置を指します。これらのレジスタは、プロシージャの開始と終了時に自動的に更新され、MCP以外のソフトウェアからはアクセスできません。Dレジスタは32個あり、これにより操作は32レベルの字句ネストに制限されます。
語彙レベル5 (D[5]) から語彙レベル2 (D[2]) のグローバル変数にアクセスする方法を考えてみましょう。変数が語彙レベル2の基底から6ワード離れているとします。つまり、アドレスペア(2, 6)で表されます。Dレジスタがない場合、D[5]フレームの基底にある制御ワードを参照する必要があります。この制御ワードは、D[4]環境を含むフレームを指しています。次に、この環境の基底にある制御ワードを参照してD[3]環境を見つけ、必要な語彙レベルまで全てのリンクをたどるまでこの手順を繰り返します。これは、この地点に到達するために呼び出されたプロシージャを戻るパスとは異なります。(アーキテクチャはデータスタックとコールスタックを同じ構造で保持しますが、制御ワードを使用して両者を区別します。)
ご覧のとおり、変数にアクセスするだけでも、これは非常に非効率的です。Dレジスタを使用すると、D[2]レジスタはレキシカルレベル2環境のベースを指し、変数のアドレスを生成するために必要なのは、スタックフレームベースからのオフセットをDレジスタ内のフレームベースアドレスに加えることだけです。(効率的なリンクリスト検索演算子LLLUがあり、上記のようにスタックを検索できますが、Dレジスタ方式の方が高速です。)Dレジスタを使用すると、外部環境およびグローバル環境のエンティティへのアクセスは、ローカル変数へのアクセスと同じくらい効率的です。
Dタグデータ — アドレスペア、コメント 登録する
| 0 | n | (4, 1) 整数n (プロシージャではなく、ブロックへの入室時に宣言される) |-----------------------| | D[4]==>3 | MSCW | (4, 0) D[3]へのリンクを含むマークスタック制御ワード。 |========================| | 0 | r2 | (3, 5) 実数r2 |-----------------------| | 0 | r1 | (3, 4) 実数r1 |-----------------------| | 1 | p2 | (3, 3) (2,6)におけるg へのSIRW参照 |-----------------------| | 0 | p1 | (3, 2) fの値からの パラメータp1 |-----------------------| | 3 | RCW | (3, 1) リターン制御ワード |-----------------------| | D[3]==>3 | MSCW | (3, 0) D[2]へのリンクを含むマークスタック制御ワード。 |========================| | 1 | a | (2, 7) 配列a ======>[10ワードのメモリブロック] |-----------------------| | 0 | g | (2, 6) 実数g |-----------------------| | 0 | f | (2, 5) 実数f |-----------------------| | 0 | k | (2, 4) 整数k |-----------------------| | 0 | j | (2, 3) 整数j |-----------------------| | 0 | i | (2, 2) 整数i |-----------------------| | 3 | RCW | (2, 1) リターン制御ワード |-----------------------| | D[2]==>3 | MSCW | (2, 0) 前のスタックフレームへのリンクを含むマークスタック制御ワード。 |========================| — スタックの底
プロシージャ p をコルーチンまたはプロセス命令として呼び出した場合、D[3] 環境は別の D[3] ベースのスタックになります。これは、ALGOL プログラム コードで暗示されているように、非同期プロセスが D[2] 環境にアクセスできることを意味します。さらに一歩進んで、まったく異なるプログラムが別のプログラムのコードを呼び出し、自身のプロセス スタックの上に別のプロセスの D[2] 環境を指す D[3] スタック フレームを作成することもできます。コードの実行環境のアドレス空間全体が瞬時に変化し、自身のプロセス スタック上の D[2] 環境は直接アドレス指定できなくなり、代わりに別のプロセス スタックの D[2] 環境が直接アドレス指定できるようになります。これがライブラリ呼び出しの実装方法です。このようなクロス スタック呼び出しでは、呼び出し元のコードと呼び出されるコードは、異なるソース言語で記述され、異なるコンパイラでコンパイルされたプログラムから生成されることさえあります。
D[1]環境とD[0]環境は、現在のプロセスのスタックには存在しません。D[1]環境はコードセグメント辞書であり、同じコードを実行するすべてのプロセスで共有されます。D[0]環境は、オペレーティングシステムによってエクスポートされるエンティティを表します。
スタックフレームは、実際にはプロセススタック内に存在する必要すらありません。この機能は、初期の頃はファイルI/Oの最適化に利用され、I/O操作中にFIB(ファイル情報ブロック)がD[1]のアドレスにある表示レジスタにリンクされていました。1990年代初頭には、この機能は言語機能としてSTRUCTURE BLOCKSとして実装され、ライブラリ技術と組み合わされてCONNECTION BLOCKSとしても利用されました。データ構造を表示レジスタのアドレス範囲にリンクする機能は、オブジェクト指向を実装するものでした。つまり、B6500は、オブジェクト指向という用語が使われるずっと前から、ある種のオブジェクト指向を利用していたのです。
他のシステムでは、コンパイラは同様の方法でシンボルテーブルを構築するかもしれませんが、最終的にはストレージ要件が調整され、マシンコードは16ビット、32ビット、あるいは64ビットのフラットなメモリ アドレスを使用するように記述されます。これらのアドレスには何でも格納できるため、誤ったアドレスに書き込むとあらゆるものが破損する可能性があります。代わりに、2部構成のアドレス方式がハードウェアによって実装されました。各字句レベルでは、変数はレベルのスタックのベースからオフセットされた位置に配置され、通常は1ワードを占めます。倍精度または複素数の変数は2ワードを占めます。配列はこの領域には格納されず、配列の1ワードの記述子のみが格納されます。したがって、各字句レベルでの総ストレージ要件は大きくなく、数十、数百、極端な場合でも数千程度であり、32ビット以上を必要とするようなカウントではありません。そして実際、これはオペランドをスタックにロードするVALC命令(値呼び出し)の形式に反映されています。このオペコードは 2 ビット長で、バイトの残りのビットは次のバイトと連結され、14 ビットのアドレス指定フィールドが作成されます。実行されるコードは、例えば 6 のような何らかのレキシカル レベルにあります。これは、レキシカル レベル 0 から 6 のみが有効であることを意味し、目的のレキシカル レベルを指定するには 3 ビットのみが必要です。したがって、VALC 操作のアドレス部分は、その目的のために 3 ビットだけを予約し、残りはそのレベルおよびそれより低いレベルのエンティティを参照するために使用できます。深くネストされたプロシージャ (つまり、高いレキシカル レベル) では、エンティティを識別するために使用できるビットが少なくなります。レベル 16 以上では、レベル 0 から 31 の選択を指定するために 5 ビットが必要となり、残りの 9 ビットで任意のレキシカル レベルの最初の 512 個のエンティティのみを識別できます。これは、32 ビットのアドレス空間でエンティティをリテラル メモリ アドレスでアドレス指定するよりもはるかにコンパクトです。さらに、データをロードしたのはVALCオペコードのみであり、ADD、MULTなどのオペコードはアドレッシングを行わず、スタックの最上位要素のみを操作していた。
Much more important is that this method meant that many errors possible on systems employing flat addressing could not occur because they were simply unspeakable even at the machine code level. A task had no way to corrupt memory in use by another task, because it had no way to develop its address. Offsets from a specified D-register would be checked by the hardware against the stack frame bound: rogue values would be trapped. Similarly, within a task, an array descriptor contained information on the array's bounds, and so any indexing operation was checked by the hardware: put another way, each array formed its own address space. In any case, the tagging of all memory words provided a second level of protection: a misdirected assignment of a value could only go to a data-holding location, not to one holding a pointer or an array descriptor, etc. and certainly not to a location holding machine code.
Arrays were not stored contiguous in memory with other variables, they were each granted their own address space, which was located via the descriptor. The access mechanism was to calculate on the stack the index variable (which therefore had the full integer range potential, not just fourteen bits) and use it as the offset into the array's address space, with bound checking provided by the hardware. By default, should an array's length exceed 1,024 words, the array would be segmented, and the index be converted into a segment index and an offset into the indexed segment. There was, however, the option to prevent segmentation by specifying the array as LONG in the declaration. In ALGOL's case, a multidimensional array would employ multiple levels of such addressing. For a reference to A[i,j], the first index would be into an array of descriptors, one descriptor for each of the rows of A, which row would then be indexed with j as for a single-dimensional array, and so on for higher dimensions. Hardware checking against the known bounds of all the array's indices would prevent erroneous indexing.
FORTRAN however regards all multidimensional arrays as being equivalent to a single-dimensional array of the same size, and for a multidimensional array simple integer arithmetic is used to calculate the offset where element A[i,j,k] would be found in that single sequence. The single-dimensional equivalent array, possibly segmented if large enough, would then be accessed in the same manner as a single-dimensional array in ALGOL. Although accessing outside this array would be prevented, a wrong value for one index combined with a suitably wrong value for another index might not result in a bounds violation of the single sequence array; in other words, the indices were not checked individually.
Because an array's storage was not bounded on each side by storage for other items, it was easy for the system to "resize" an array - though changing the number of dimensions was precluded because compilers required all references to have the same number of dimensions. In ALGOL's case, this enabled the development of "ragged" arrays, rather than the usual fixed rectangular (or higher dimension) arrays. Thus in two dimensions, a ragged array would have rows that were of different sizes. For instance, given a large array A[100,100] of mostly-zero values, a sparse array representation that was declared as SA[100,0] could have each row resized to have exactly enough elements to hold only the non-zero values of A along that row.
Because arrays larger than 1024 words were generally segmented but smaller arrays were not, on a system that was short of real memory, increasing the declared size of a collection of scratchpad arrays from 1,000 to say 1,050 could mean that the program would run with far less "thrashing" as only the smaller individual segments in use were needed in memory. Actual storage for an array segment would be allocated at run time only if an element in that segment were accessed, and all elements of a created segment would be initialised to zero. Not initialising an array to zero at the start therefore was encouraged by this, normally an unwise omission.
Array equivalencing is also supported. The ARRAY declaration requested allocation of 48-bit data words which could be used to store any bit pattern but the general operational practice was that each allocated word was considered to be a REAL operand. The declaration of:
ARRAY A [0:99]
requested the allocation of 100 words of type REAL data space in memory. The programmer could also specify that the memory might be referred to as character oriented data by the following equivalence declaration:
EBCDIC ARRAY EA [0] = A [*];
or as hexadecimal data via the equivalence declaration:
HEX ARRAY HA [0] = A [*];
or as ASCII data via the equivalence declaration:
ASCII ARRAY AA [0] = A[*];
The capability to request data type specific arrays without equivalencing is also supported, e.g.
EBCDIC ARRAY MY_EA [0:99]
requested that the system allocated a 100 character array. Given that the architecture is word based, the actual space allocated is the requested number of characters rounded up to the next whole word boundary.
The Data Descriptor generated at compilation time indicated the data type usage for which the array was intended. If an array equivalence declaration was made a copy descriptor indicating that particular usage type was generated but pointed back to the original, or MOM, descriptor. Thus, indexing the correct location in memory was always guaranteed.
BOOLEAN arrays are also supported and may be used as a bit vector. INTEGER arrays may also be requested.
直前の説明では、配列宣言を説明するためにALGOLの構文実装を使用していますが、同じ機能はCOBOLとFORTRANでもサポートされています。
スタック構造の利点の1つは、プログラムが万が一エラーを起こした場合、スタックダンプが取得されるため、プログラマーは実行中のプログラムの状態を正確に把握することが非常に容易である点です。他のシステムのコアダンプや交換パッケージと比較してみてください。
スタック構造のもう一つの特徴は、プログラムが暗黙的に再帰的であることです。FORTRANは再帰をサポートするとは想定されておらず、ALGOLの実装方法を理解する上での障害の一つは、再帰をどのように実装するかという点だったのかもしれません。B5000では、これは問題になりませんでした。実際、彼らは逆の問題、つまりプログラムが再帰的にならないようにする方法に直面していました。結局、彼らはその問題に取り組まなかったのです。BurroughsのFORTRANコンパイラは(他のすべてのFORTRANコンパイラと同様に)再帰呼び出しを許可していましたが、他の多くのコンピュータとは異なり、スタックベースのシステムでは、そのような呼び出しからの戻り値も成功しました。これは、数式の形式的な操作を行うシステムで、中心となるサブルーチンが互いに繰り返し呼び出し合い、決して戻り値を返さないような場合、奇妙な影響をもたらす可能性がありました。大規模なジョブはスタックオーバーフローによって終了してしまったのです。
このように、Burroughs FORTRANは、同時代の他のFORTRAN実装よりも優れたエラーチェック機能を備えていました。例えば、サブルーチンや関数については、ALGOLスタイルのコンパイラでは一般的なように、正しい数のパラメータで呼び出されているかどうかをチェックしていました。他のコンピュータでは、このような不一致はクラッシュの一般的な原因でした。配列境界チェックについても同様で、他のシステムで長年使用されてきたプログラムが、Burroughsシステムで実行すると、恥ずかしいほど頻繁に失敗しました。実際、Burroughsは、オブジェクト指向のSimula(ALGOLの上位互換)を含む、優れたコンパイラと言語実装で知られるようになり、APLの設計者であるIversonは、 BurroughsのAPL実装は自分が見た中で最高だと宣言しました。LISPの言語設計者であるJohn McCarthyはこれに異議を唱え、 LISPは変更可能なコードに基づいているため、B5000の変更不可能なコードを好まなかったのですが、ほとんどのLISP実装はいずれにせよインタプリタ環境で実行されることに変わりはありませんでした。
複数のプロセスに必要なストレージは、必要に応じてシステムのメモリプールから供給されました。競合システムのように、タスクを実行するためのメモリパーティションを事前に構成するために、BurroughsシステムでSYSGENを実行する必要はありませんでした。
B5000の最も特徴的な点は、前述のようにスタックマシンであることです。しかし、このアーキテクチャのもう2つの非常に重要な特徴は、タグベースかつディスクリプタベースであることです。
オリジナルのB5000では、各制御ワードまたは数値ワード[ NB 7 ]にフラグビットが設けられ、そのワードが制御ワードか数値ワードかを識別できるようになっていました。これは、プログラムがスタック上の制御ワードを改ざんするのを防ぐためのセキュリティ機構の一環でした。
その後、B6500が設計された際、1ビットの制御ワード/数値の区別が強力なアイデアであることが認識され、48ビットワードの外側の3ビットをタグとして拡張されました。データビットはビット0~47、タグはビット48~50です。ビット48は読み取り専用ビットであったため、奇数番目のタグは、ユーザーレベルのプログラムで書き込むことができない制御ワードを示しました。コードワードにはタグ3が割り当てられました。以下に、タグとその機能の一覧を示します。
内部的には、一部のマシンは60ビットワードを使用しており、余分なビットはハミング符号の誤り訂正フィールドなどのエンジニアリング目的で使用されていたが、プログラマーがこれらを見ることはなかった。
これらのマシンの現行バージョンであるUnisys ClearPathは、タグをさらに拡張し、4ビットタグを実現しました。4ビットタグを規定したマイクロコードレベルは、ガンマレベルと呼ばれていました。
偶数タグのワードは、ユーザープログラムによってユーザー状態として変更可能なユーザーデータです。奇数タグのワードはハードウェアによって直接生成および使用され、プログラムの実行状態を表します。これらのワードは特定の命令またはハードウェアによって生成および消費されるため、ハードウェアの実装によってワードの正確なフォーマットが変わる可能性がありますが、システムワードのフォーマットが変わっても、同じコードストリームは同じ結果を生成するため、ユーザープログラムを再コンパイルする必要はありません。
タグ1ワードは、スタック上のデータアドレスを表します。通常のIRWは、現在のスタック上のデータに対応するアドレスペアを単純に格納します。SIRWは、アドレスにスタック番号を含めることで、任意のスタック上のデータを参照します。SIRWは、CALL文やPROCESS文に応じて生成されるような、個別のプロセススタック間のアドレス指定を提供するなど、様々な用途に使用されます。
タグ5の単語は記述子であり、次のセクションでより詳しく説明します。タグ5の単語は、スタック外のデータアドレスを表します。
タグ7は、プロシージャのエントリポイントを示すプログラム制御ワードです。ハードウェアオペレータがPCWに到達すると、プロシージャが実行されます。ENTRオペレータは、プロシージャ(値を返さないルーチン)を明示的に実行します。関数(値を返すルーチン)は、値呼び出し(VALC)などのオペレータによって暗黙的に実行されます。グローバルルーチンは、D[1]環境のコードセグメント辞書に格納されているPCWを指すSIRWとして、D[2]環境に格納されます。D[1]環境は、このコードを共有するすべてのプロセスから参照できるため、現在のスタックには格納されません。したがって、コードは再入可能で共有されます。
タグ3はコードワード自体を表し、スタック上には出現しません。タグ3は、スタック制御ワードであるMSCW、RCW、TOSCWにも使用されます。

左の図は、バローズ・ラージ・システム・アーキテクチャが、根本的にはオブジェクト指向プログラミングのためのハードウェア・アーキテクチャであったことを示している。これは、従来のアーキテクチャにはまだ存在しない特徴である。
バロウズの大規模システムには、3つの異なる命令セットが存在する。これら3つはすべて、単語に均等に収まる短い音節に基づいている。
B5000、B5500、B5700 のプログラムは12 ビットの音節で構成され、1 ワードは 4 ビットです。アーキテクチャにはワード モードと文字モードの 2 つのモードがあり、それぞれに異なる音節のレパートリーがあります。プロセッサは制御状態または通常状態のいずれかになり、特定の音節は制御状態でのみ使用できます。アーキテクチャではレジスタやストレージを直接アドレス指定することはできません。すべての参照は、1024 ワードのプログラム参照テーブル、現在のコード セグメント、スタック内のマークされた位置、またはスタックの上位 2 つの位置を保持する A レジスタと B レジスタを介して行われます。Burroughs は音節のビットを 0 (最上位ビット) から 11 (最下位ビット) まで番号付けします。
プログラムは8 ビットの音節で構成され、音節は名前呼び出し、値呼び出し、または演算子を形成します。演算子の長さは 1 ~ 12 音節です。演算子は200 未満で、すべて 8 ビットの音節に収まります。これらの演算子の多くは、タグによって指定される操作対象のデータの種類に応じて多態性があります。強力な文字列スキャン、転送、編集演算子を無視すると、基本セットは約 120 個の演算子になります。MVST や HALT など、オペレーティングシステム用に予約されている演算子を除外すると、ユーザー レベル プログラムで一般的に使用される演算子のセットは 100 未満になります。名前呼び出しと値呼び出しの音節にはアドレス ペアが含まれます。演算子音節はアドレスを使用しないか、スタック上の制御ワードと記述子を使用します。
B5000 シリーズは、マスターとスレーブとして高速バス上で 2 つのプロセッサが接続されるという点でも先駆的でした。B6000、B7000、B8000 シリーズでは、プロセッサは対称的でした。B7000 シリーズは、少なくとも 1 つが I/O モジュールであれば、最大 8 つのプロセッサを搭載できました。RDLK (ReaD with LocK)は、プロセッサ間の同期を行う非常に低レベルの方法です。RDLKは1 サイクルで動作します。ユーザー プログラムで一般的に使用される高レベルのメカニズムは、EVENTデータ型です。EVENTデータ型には、システム オーバーヘッドがありました。このオーバーヘッドを回避するために、Dahm ロック (Burroughs のソフトウェア グルである Dave Dahm にちなんで命名) と呼ばれる特別なロック技術を使用できます。Dahm ロックは、コードレベルでRDLK演算子を生成するREADLOCK ALGOL 言語ステートメントを使用しました。
注目すべき事業者は以下のとおりです。
HEYU — 他のプロセッサに割り込みを送信する RDLK — 低レベルセマフォ演算子: Aレジスタで指定されたメモリ位置をAレジスタにロードし、そのメモリ位置にあるBレジスタに値を単一の割り込み不可能なサイクルで配置します。Algolコンパイラは、明示的な一時値なしで単一ワードデータに対して「スワップ」操作を可能にする特別な関数を介してこの演算子を呼び出すコードを生成しました。x:=RDLK(x,y);WHOI — プロセッサ識別 IDLE — 割り込みを受信するまでアイドル状態
まれに、2つのプロセッサが同時に「HEYU」コマンドを送信することがあり、その結果、「致命的な抱擁」と呼ばれるフリーズが発生する可能性がある。
B5000 の直接的な影響は、B5000 の影響を受けた B6500 の直系の子孫であり、40 年にわたる継続的な開発を経ても MCP オペレーティングシステムを搭載している現在の Unisys ClearPath メインフレームシリーズに見られます。このアーキテクチャは現在、emode (エミュレーションモード) と呼ばれています。これは、B6500 アーキテクチャが、ネイティブ命令セットとしてx86命令セットを実行するIntel Xeonプロセッサで構築されたマシンに実装され、これらのプロセッサ上で B5000 命令セットをエミュレートするコードが実行されているためです。これらのマシンには nmode (ネイティブモード) も搭載される予定でしたが、これは廃止されたため、B6500 の後継マシンが「emode マシン」と呼ばれることがよくあります。
B5000マシンは高級言語のみでプログラミングされており、アセンブラは存在しない。
B5000スタックアーキテクチャは、プログラミング言語Forthの設計者であるチャック・ムーアにインスピレーションを与えました。ムーアはMIT在学中にB5500に出会いました。著書『Forth - The Early Years』の中で、ムーアはその影響について述べており、ForthのDUP、DROP、SWAP命令は、対応するB5500命令(DUPL、DLET、EXCH)に由来すると指摘しています。
スタックベースのアーキテクチャとタグ付きメモリを備えたB5000マシンは、ソ連のElbrusシリーズのメインフレームやスーパーコンピュータにも大きな影響を与えた。このシリーズの最初の2世代は、タグ付きメモリとスタックベースのCPUを搭載し、プログラミングは高級言語のみで行われた。El -76と呼ばれるアセンブリ言語のようなものも存在したが、これはALGOL 68の改良版であり、構造化プログラミングと第一級手続きをサポートしていた。しかし、後の世代では、このアーキテクチャからEPICのようなVLIW CPUへと移行した。
HP 3000ビジネスシステムの設計者たちは、B5500を使用しており、そのハードウェアとソフトウェアに非常に感銘を受けていました。彼らは、同様のソフトウェアを備えた16ビットミニコンピュータの構築を目指しました。HPの他のいくつかの部門も、同様のミニコンピュータまたはマイクロプロセッサスタックマシンを開発しました。ボブ・バートンによる逆ポーランド記法(RPN)の研究も、 9100Aを皮切りに、特にHP-35とその後の電卓をはじめとするHPの電卓に採用されました。
1970年代後半から1980年代初頭にかけてタンデム・コンピュータが設計したノンストップ・システムも16ビット・スタック・マシンであり、初期のタンデムのエンジニア数名が以前HPに在籍していたことから、HP 3000との繋がりを通じてB5000の影響を間接的に受けていた。1990年頃、これらのシステムはMIPS RISCアーキテクチャに移行したが、オブジェクトコード変換または直接エミュレーションによってスタック・マシン・バイナリの実行を引き続きサポートした。2000年以降のある時期に、これらのシステムはイタニウム・アーキテクチャに移行したが、従来のスタック・マシン・バイナリの実行は継続された。
ボブ・バートンはアラン・ケイにも大きな影響を与えた。ケイはB5000のデータ駆動型タグ付きアーキテクチャにも感銘を受け、それがオブジェクト指向プログラミングやSmalltalkの開発における彼の考え方に影響を与えた。
B5000アーキテクチャのもう一つの特徴は、ハードウェア上で直接動作するセキュアなアーキテクチャであったことです。この技術は、今日の仮想マシンがセキュアな環境を提供しようとする試みにおいて、後継の技術として受け継がれています。その代表的な例の一つがJava JVMであり、アプリケーションが実行されるセキュアなサンドボックスを提供します。
emode以前に存在していたハードウェアとアーキテクチャの結合の価値は、 MCPが唯一の制御プログラムであった限り、 x86ベースのマシンでも実質的に維持されるだろうが、それらのマシンが提供するサポートは、B6500命令セットがネイティブ命令セットであるマシンが提供するサポートにはまだ劣る。実際にはx86命令セットの32ビット実装よりも前に存在した、あまり知られていないIntelプロセッサアーキテクチャであるIntel iAPX 432は、本質的にオブジェクト指向アーキテクチャであったため、同等の物理的基盤を提供しただろう。
{{cite book}}ISBN /日付の不一致(ヘルプ)