私はいつもこれを疑問に思っており、おそらくプログラミング言語に関する良い歴史のレッスンが必要です。しかし、最近のほとんどのコンパイラはCで作成されているため、最初のコンパイラ(C以前の別名)はどのように作成されましたか?
とはいえ、最初のアセンブリ言語がどのように行われたかはまだわかりません、アセンブリ言語とは何ですか?コマンド(などmov R21
)または同等のバイナリに設定されたw / e?
私はいつもこれを疑問に思っており、おそらくプログラミング言語に関する良い歴史のレッスンが必要です。しかし、最近のほとんどのコンパイラはCで作成されているため、最初のコンパイラ(C以前の別名)はどのように作成されましたか?
とはいえ、最初のアセンブリ言語がどのように行われたかはまだわかりません、アセンブリ言語とは何ですか?コマンド(などmov R21
)または同等のバイナリに設定されたw / e?
回答:
ハ、私はこれをやった。多くのCPUには、長さがわずか数バイトの単純な固定サイズの命令があります。たとえば、Motorola 6800などの単純なCPUの場合、そのすべての指示を1 枚の用紙に収めることができます。各命令には、それに関連付けられた2バイトのオペコードと引数があります。各命令のオペコードを調べることで、プログラムを手作業で組み立てることができます。次に、プログラムを紙に書き、各命令に対応するオペコードを注釈します。プログラムを作成したら、各オペコードを順番にEPROMに書き込むことができます。その後、プログラムが保存されます。EPROMをCPUに配線し、適切な命令を適切なアドレスに置くだけで、簡単な作業プログラムができます。そして、次の質問に答えるために、はい。苦しかったです(高校でこれを行いました)。しかし、8ビットコンピューターのすべてのチップを配線し、プログラムを手動で記述することで、他の方法では達成できなかったコンピューターアーキテクチャの深い理解が得られたと言わざるを得ません。
より高度なチップ(x86など)は、多くの場合可変長命令を持っているため、ハンドコーディングがはるかに困難です。ItaniumなどのVLIW / EPICプロセッサは、高度なコンパイラによって最適化およびアセンブルされた命令のパケットを処理するため、効率的にハンドコーディングすることはほぼ不可能です。新しいアーキテクチャの場合、プログラムはほとんどの場合最初に別のコンピューターで作成およびアセンブルされ、次に新しいアーキテクチャにロードされます。実際、実際にCPUを構築するIntelのような企業では、シミュレータで実行することにより、まだ存在しないアーキテクチャで実際のプログラムを実行できます。しかし、私は脱線します...
コンパイラに関しては、非常に単純な場合、「カットアンドペースト」プログラムにすぎません。非常に単純で最適化されていない「高レベル言語」を記述できます。これは、多くの労力をかけずに単純なアセンブリ言語命令をまとめてクラスター化するだけです。
コンパイラとプログラミング言語の履歴が必要な場合は、FORTRANの履歴に移動することをお勧めします。
これがコンパイラのブートストラップの目的です(=と呼ばれる方法について誰も言及していないため)。
コンパイル対象のターゲットプログラミング言語でコンパイラー(またはアセンブラー)を作成するプロセス。この手法を適用すると、セルフホスティングコンパイラが実現します。
BASIC、ALGOL、C、Pascal、PL / I、Factor、Haskell、Modula-2、Oberon、OCaml、Common Lisp、Scheme、Java、Python、Scalaなどのコンパイラを含む、多くのプログラミング言語の多くのコンパイラがブートストラップされています。 。
鶏と卵の問題
言語Xのコンパイラ(言語Xで記述されている)を取得するために言語Xのコンパイラが必要な場合、最初のコンパイラはどのように記述されましたか?この鶏または卵の問題を解決する可能な方法は次のとおりです。
- 言語Xのインタプリタまたはコンパイラを言語Yに実装しました。NiklausWirthは、Fortranで最初のPascalコンパイラを書いたと報告しました。
- X用の別のインタープリターまたはコンパイラーは、すでに別の言語Yで作成されています。これはSchemeがしばしばブートストラップされる方法です。
- コンパイラの以前のバージョンは、他のコンパイラが存在するXのサブセットで記述されていました。これが、Java、Haskell、および初期のFree Pascalコンパイラのいくつかのスーパーセットがブートストラップされる方法です。
- Xのコンパイラは、Xのコンパイラが存在する別のアーキテクチャからクロスコンパイルされます。これは通常、Cコンパイラが他のプラットフォームに移植される方法です。また、これは初期ブートストラップ後にFree Pascalに使用される方法です。
- Xでコンパイラを作成します。次に、ソースから手動でコンパイルし(最適化されていない方法が最も可能性が高い)、コード上で実行して最適化されたコンパイラを取得します。ドナルド・クヌースはこれを自分のWEBリテラシープログラミングシステムに使用しました...
最終的に、すべてのコンピューターはバイナリコードで動作し、CPUに供給されます。これらのバイナリコードはCPUにとって完全に自然ですが、人間にとってもまったく役に立ちません。プログラムを書く最初の方法の1つは、カードに穴を開けることでした。穴の位置は単語内の特定のビット位置を表し、穴の有無はゼロまたは1として解釈されました。これらのカードはボックス内の正しいシーケンスに入れられ、カードリーダーに送られ、CPUのバイナリコードに効果的に変換されました(ボックスを落とした場合、あなたの人生は事実上失われました)。
明らかに、最初のプログラマーはバイナリコードを1つずつ作成し、カードをパンチするマシンを用意しました。これは基本的に、あなたの手とひざの上のアセンブリ言語プログラミングです。それができたら、他のすべてのものを作成できます:単純なテキストエディター、アセンブリ言語コンパイラ(テキストアセンブリステートメントをバイナリコードに変換するため)、リンカー、ローダー。そして、彼らが言うように、残りは歴史です。
少しグーグルで40代後半からEDSACの初期注文が表示されます。これは最初のアセンブラーであるため、おそらく機械語でコーディングされていました。
後に、IBM 650用のSOAP IおよびIIのような他のマシン用のアセンブラーが登場しました。SOAPIもおそらく機械語でコーディングされていましたが、最終的なステートメントは見つかりませんでした。
少し後に、IBM 704用のFortran(式変換プログラム)が登場しました。おそらく、704用のアセンブラーで書かれたものです。701用の初期のアセンブラーはNathan Rochesterの功績によるものです。
コンピューターを機械語でプログラムする方法を知りたい場合は、私のお気に入りのサイトの1つであるHarry Porterのリレーコンピューターをチェックしてください。
(退屈な場合)直接マシンコードを書くことは可能です。多分あなたは紙の上にアセンブラーでプログラムを書き留めて、それからあなたが手で機械メモリに入力する数値の機械コード命令に翻訳します。すべてのマシンコード命令の数値を記憶している場合は、紙の上のアセンブラーの手順をスキップすることもできます。
最初のコンピューターは、物理スイッチを切り替えることにより、バイナリで直接プログラムされました。ハードウェアが進化してプログラマー(またはデータ入力アシスタント)がキーパッドを介して16進数のコードを入力できるようになったとき、生産性が大幅に向上しました。
ソフトウェアアセンブラは、アセンブラコードがrawマシンコードよりも多くのスペースを占有するため)より多くのメモリが使用可能になり、英数字入力を許可するように進化した場合にのみ関連しました。したがって、最初のアセンブラは、マシンコードに堪能な人々によって直接記述されました。
アセンブラーがある場合、アセンブラーで高レベル言語用のコンパイラーを作成できます。
Cのストーリーには複数のステップがあります。最初のCコンパイラはB(Cの前身)で書かれ、BCPLで書かれました。BCPLは非常に単純な言語です(たとえば、型がまったくありません)が、未加工のアセンブラーからのステップアップです。したがって、アセンブラーに至るまで、より複雑な言語がより単純な言語で徐々に構築されることがわかります。そして、C自体は今日の標準ではかなり小さくシンプルな言語です。
今日、新しい言語の最初のコンパイラはCで書かれていることがよくありますが、言語が特定の成熟度に達すると、しばしば「それ自体」で書き直されます。最初のJavaコンパイラはCで記述されていましたが、後にJavaで書き直されました。最初のC#コンパイラはC ++で記述されていましたが、最近ではC#で書き直されました。Pythonコンパイラ/インタープリターはCで書かれていますが、PyPyプロジェクトはPythonで書き直そうとしています。
ただし、言語自体に言語用のコンパイラ/インタープリターを書くことは常に実行可能ではありません。JavaScriptで記述されたJavaScriptインタープリターは存在しますが、現在のブラウザーのコンパイラー/インタープリターは、パフォーマンス上の理由からCまたはC ++で記述されています。JavaScriptで記述されたJavaScriptは単純に遅すぎます。
ただし、コンパイラの「開始言語」としてCを使用する必要はありません。最初のF#コンパイラはOCamlで作成されました。これは、F#に最も密接に関連する他の言語です。コンパイラが完成すると、F#で書き直されました。Perl 6の最初のコンパイラーはHaskell(Perlとは非常に異なる純粋な関数型言語)で作成されましたが、現在はCで作成されたコンパイラーがあります。
興味深いケースはRustです。最初のコンパイラはOCamlで記述されています(現在はRustで書き直されています)。OCamlは一般的にRustよりも高いレベルと考えられているため、これは注目に値します。Rustは、より金属に近いシステム言語です。したがって、常に低レベル言語で実装された高レベル言語であるとは限らず、逆の場合もあります。