it-swarm.com.de

Wie sind die ersten Compiler entstanden?

Ich frage mich immer, und vielleicht brauche ich eine gute Geschichtsstunde über Programmiersprachen. Aber da die meisten Compiler heutzutage in C erstellt werden, wie wurden die ersten Compiler erstellt (AKA vor C) oder wurden alle Sprachen nur interpretiert?

Nachdem dies gesagt wurde, verstehe ich immer noch nicht, wie selbst die erste Assemblersprache erstellt wurde. Ich verstehe, was Assemblersprache ist, aber ich sehe nicht, wie sie die SEHR erste Assemblersprache zum Laufen gebracht haben (wie haben sie die erste erstellt? Befehle (wie mov R21) oder w/e auf das binäre Äquivalent gesetzt?

70
user6791

Ha, ich habe das getan. Viele CPUs verfügen über einfache Anweisungen mit fester Größe, die nur einige Bytes lang sind. Bei einer einfachen CPU wie beispielsweise einem Motorola 6800 können Sie alle Anweisungen auf ein einzelnes Blatt Papier setzen. Jedem Befehl wären ein Zwei-Byte-Opcode und Argumente zugeordnet. Sie können ein Programm von Hand zusammenstellen, indem Sie den Opcode jeder Anweisung nachschlagen. Sie würden dann Ihr Programm auf Papier schreiben und jede Anweisung mit dem entsprechenden Opcode versehen. Sobald Sie Ihr Programm ausgeschrieben haben, können Sie jeden Opcode nacheinander auf ein EPROM brennen, das dann Ihr Programm speichert. Verbinden Sie das EPROM mit genau den richtigen Anweisungen an den richtigen Adressen mit der CPU, und Sie haben ein einfaches Arbeitsprogramm. Und um Ihre nächste Frage zu beantworten, ja. Es war schmerzhaft (wir haben das in der High School gemacht). Aber ich muss sagen, dass die Verkabelung jedes Chips in einem 8-Bit-Computer und das manuelle Schreiben eines Programms mir ein tiefes Verständnis der Computerarchitektur verlieh, das ich wahrscheinlich auf keine andere Weise hätte erreichen können.

Fortgeschrittenere Chips (wie x86) sind weitaus schwieriger von Hand zu codieren, da sie häufig Anweisungen mit variabler Länge enthalten. VLIW/EPIC-Prozessoren wie Itanium können kaum effizient von Hand codiert werden, da sie Anweisungspakete verarbeiten, die von fortschrittlichen Compilern optimiert und zusammengestellt werden. Bei neuen Architekturen werden Programme fast immer zuerst auf einem anderen Computer geschrieben und zusammengestellt und dann in die neue Architektur geladen. Firmen wie Intel, die tatsächlich CPUs bauen, können tatsächliche Programme auf Architekturen ausführen, die noch nicht existieren, indem sie sie auf Simulatoren ausführen. Aber ich schweife ab...

Compiler können im einfachsten Fall kaum mehr als "Ausschneiden und Einfügen" -Programme sein. Sie könnten eine sehr einfache, nicht optimierende "Hochsprache" schreiben, die einfache Anweisungen in Assemblersprache ohne großen Aufwand zusammenfasst.

Wenn Sie eine Geschichte von Compilern und Programmiersprachen wollen, empfehle ich Ihnen, eine Geschichte von FORTRAN .

89
Dave Markle

Darum geht es bei Compiler Bootstrapping (da niemand erwähnt hat, wie es heißt =).

der Prozess des Schreibens eines Compilers (oder Assemblers) in der Zielprogrammiersprache, die kompiliert werden soll. Die Anwendung dieser Technik führt zu einem selbsthostenden Compiler.

Viele Compiler für viele Programmiersprachen sind gebootet, einschließlich Compiler für BASIC, ALGOL, C, Pascal, PL/I, Faktor, Haskell, Modula-2, Oberon, OCaml, Common LISP, Schema, Java, Python, Scala und mehr ...

Das Henne-Ei-Problem

Wenn man einen Compiler für Sprache X benötigt, um einen Compiler für Sprache X (der in Sprache X geschrieben ist) zu erhalten, wie wurde der erste Compiler geschrieben? Mögliche Methoden zur Lösung dieses Hühner- oder Ei-Problems sind:

  • Implementierung eines Interpreters oder Compilers für Sprache X in Sprache Y. Niklaus Wirth berichtete, dass er den ersten Pascal-Compiler in Fortran geschrieben hat.
  • Ein anderer Interpreter oder Compiler für X wurde bereits in einer anderen Sprache Y geschrieben. Auf diese Weise wird das Schema häufig gebootet.
  • Frühere Versionen des Compilers wurden in eine Teilmenge von X geschrieben, für die es einen anderen Compiler gab. Auf diese Weise werden einige Obermengen von Java, Haskell und dem anfänglichen Free Pascal-Compiler gebootet.
  • Der Compiler für X wird aus einer anderen Architektur kompiliert, in der ein Compiler für X vorhanden ist. Auf diese Weise werden Compiler für C normalerweise auf andere Plattformen portiert. Dies ist auch die Methode, die für Free Pascal nach dem ersten Bootstrap verwendet wird.
  • Schreiben des Compilers in X; Kompilieren Sie es dann von Hand aus dem Quellcode (höchstwahrscheinlich nicht optimiert) und führen Sie es auf dem Code aus, um einen optimierten Compiler zu erhalten. Donald Knuth verwendete dies für sein WEB-Programmiersystem ...
54
vines

Letztendlich arbeiten alle Computer mit Binärcodes, die in die CPU eingespeist werden. Diese Binärcodes sind für eine CPU völlig natürlich, für Menschen aber auch völlig nutzlos. Eine der ersten Möglichkeiten, ein Programm zu schreiben, bestand darin, Löcher in Karten zu stanzen. Die Position der Löcher stellte eine bestimmte Bitposition innerhalb eines Wortes dar, und das Vorhandensein oder Fehlen des Lochs wurde als Null oder Eins interpretiert. Diese Karten wurden in einer Box in die richtige Reihenfolge gebracht und dann in einen Kartenleser eingespeist, der sie effektiv in Binärcode für die CPU umwandelte (und Ihr Leben verfiel effektiv, wenn Sie die Box fallen ließen).

Offensichtlich haben die allerersten Programmierer die Binärcodes einzeln ausgearbeitet und hatten eine Maschine, um die Karten zu lochen. Dies ist im Wesentlichen die Assembler-Programmierung auf Händen und Knien. Sobald Sie das haben, können Sie alle anderen Dinge daraus erstellen: einen einfachen Texteditor, einen Assembler-Compiler (um die Assembly-Anweisungen in Binärcodes umzuwandeln), einen Linker und einen Loader. Und der Rest ist, wie sie sagen, Geschichte.

15
wolfgangsz

Ein wenig googeln taucht auf EDSAC Initial Orders aus den späten 40ern. Da es der erste Assembler war, wurde es wahrscheinlich in Maschinensprache codiert.

Später kamen Assembler für andere Maschinen, wie SOAP I und II für IBM 650. SOAP Ich wurde wahrscheinlich auch in Maschinensprache codiert, obwohl ich die nicht gefunden habe endgültige Aussage.

Wenig später kam Fortran (Formelübersetzer) für die IBM 704. Vermutlich wurde es in Assembler für die 704 geschrieben. Ein früher Assembler für die 701 wird Nathan Rochester gutgeschrieben.

Wenn Sie eine Vorstellung davon bekommen möchten, wie man einen Computer in Maschinensprache programmiert, schauen Sie sich eine meiner Lieblingsseiten an: Harry Porters Relay-Computer .

7
Mike Dunlavey

Es ist möglich (wenn auch mühsam), direkten Maschinencode zu schreiben. Vielleicht schreiben Sie das Programm in Assembler auf ein Blatt Papier und übersetzen es dann von Hand in die numerischen Maschinencode-Anweisungen, die Sie in den Maschinenspeicher eingeben. Sie können den Assembler-on-Paper-Schritt sogar überspringen, wenn Sie die numerischen Werte aller Maschinencode-Anweisungen gespeichert haben - in jenen Tagen nicht ungewöhnlich, ob Sie es glauben oder nicht!

Die allerersten Computer wurden durch Umschalten der physischen Schalter direkt binär programmiert. Es war eine große Produktivitätsverbesserung, als die Hardware weiterentwickelt wurde, damit der Programmierer (oder der Dateneingabeassistent) Code in Hexadezimalzahlen über eine Tastatur eingeben konnte!

Ein Software-Assembler wurde erst relevant, als mehr Speicher verfügbar wurde (da Assembler-Code mehr Platz als roher Maschinencode einnimmt) und die Hardware weiterentwickelt wurde, um alphanumerische Eingaben zu ermöglichen. Die ersten Assembler wurden also direkt von Personen geschrieben, die fließend Maschinencode beherrschen.

Wenn Sie einen Assembler haben, können Sie im Assembler einen Compiler für eine höhere Sprache schreiben.

Die Geschichte für C besteht aus mehreren Schritten. Der erste C-Compiler wurde in B (einem Vorgänger von C) geschrieben, der wiederum in BCPL geschrieben wurde. BCPL ist eine ziemlich einfache Sprache (zum Beispiel hat sie überhaupt keine Typen), aber immer noch ein Schritt weiter als Raw Assembler. Sie sehen also, wie allmählich komplexere Sprachen in einfacheren Sprachen bis hin zum Assembler erstellt werden. Und selbst C ist für heutige Verhältnisse eine ziemlich kleine und einfache Sprache.

Heutzutage wird der erste Compiler für eine neue Sprache oft in C geschrieben, aber wenn die Sprache eine bestimmte Reife erreicht, wird sie oft "in sich selbst" umgeschrieben. Der erste Java Compiler wurde in C geschrieben, aber später in Java neu geschrieben. Der erste C # Compiler wurde in C++ geschrieben, aber kürzlich wurde er in C # neu geschrieben. Der Python Compiler/Interpreter ist in C geschrieben, aber das PyPy-Projekt ist ein Versuch, es in Python neu zu schreiben.

Es ist jedoch nicht immer möglich, einen Compiler/Interpreter für eine Sprache in der Sprache selbst zu schreiben. Ein in JavaScript geschriebener JavaScript-Interpreter ist vorhanden, aber die Compiler/Interpreter in aktuellen Browsern sind aus Leistungsgründen weiterhin in C oder C++ geschrieben. In JavaScript geschriebenes JavaScript ist einfach zu langsam.

Sie müssen jedoch nicht C als "Startsprache" für einen Compiler verwenden. Der erste F # -Compiler wurde in OCaml geschrieben, der anderen Sprache, die am engsten mit F # verwandt ist. Wenn der Compiler fertig war, wurde er in F # neu geschrieben. Der erste Compiler für Perl 6 wurde in Haskell geschrieben (eine reine Funktionssprache sehr anders als Perl), hat aber jetzt einen Compiler in C.

Ein interessanter Fall ist Rust, wo der erste Compiler in OCaml geschrieben wurde (jetzt wird er in Rust umgeschrieben). Dies ist insofern bemerkenswert, als OCaml im Allgemeinen als höher eingestuft wird als Rust, eine Sprache, die näher am Metall liegt. Es handelt sich also nicht immer um übergeordnete Sprachen, die in untergeordneten Sprachen implementiert sind, sondern möglicherweise auch umgekehrt.

6
JacquesB

Angenommen, Sie beginnen mit einem bloßen Befehlssatz und nichts anderem, dann erstellen Sie zunächst einen minimal, kaum funktionierenden Assembler oder Compiler, der eine Datei laden kann, und analysieren eine minimale Teilmenge des Zielsprache und generieren Sie eine ausführbare Datei als Ausgabe, indem Sie den Rohmaschinencode mit einem Hex-Editor oder ähnlichem schreiben.

Sie würden dann diesen kaum funktionierenden Compiler oder Assembler verwenden, um einen etwas leistungsfähigeren Compiler oder Assembler zu implementieren, der eine größere Teilmenge der Zielsprache erkennen kann. Schäumen, ausspülen, wiederholen, bis Sie das Endprodukt haben.

3
John Bode

Es ist nicht so schwierig, wie es scheint. In der Kindheit;) habe ich mir eine x86-Demontage vorgenommen.

Sie müssen es nicht einmal besonders lernen. Es passiert einfach, wenn Sie in ASM programmieren können und dann versuchen, eine Binärdatei eines Drittanbieters mithilfe interaktiver Disassembler zu reparieren. Oder wenn Sie Ihren eigenen Schutz mit Codeverschlüsselung schreiben.

Das heißt, Manchmal migrieren Sie sogar ohne Wunder von der Sprache zu den Codes.

2
Pavel Koryagin

Die ersten Compiler wurden in Assemblersprache implementiert. Und die ersten Assembler wurden durch Codierung von Programmen in binären ...


Es ist noch nicht so lange her, dass das Programmieren in Binärform noch eine Fähigkeit war, die die Leute benutzten.

Als ich ein Student war, erinnere ich mich an eine Programmierübung, bei der ein winziges Programm in PDP-8-Maschinencode (glaube ich) geschrieben, über die Schalter auf der Vorderseite eingegeben und ausgeführt wurde. Ein paar Jahre später kaufte ich mir ein 6502-Systementwicklungskit mit einer Hex-Tastatur zur Eingabe von Programmen ... und 4 KB RAM.

1
Stephen C