Как были сделаны первые компиляторы?


70

Мне всегда интересно это, и, возможно, мне нужен хороший урок истории по языкам программирования. Но так как большинство компиляторов в настоящее время сделаны на C, как были созданы самые первые компиляторы (AKA до C) или все языки были просто интерпретированы?

С учетом вышесказанного, я до сих пор не понимаю, как был создан даже первый язык ассемблера, я понимаю, что такое язык ассемблера, но я не вижу, как они получили ОЧЕНЬ первый язык ассемблера (например, как они сделали первый Команды (как mov R21) или W / E установлен в двоичный эквивалент?


9
Однажды в моей команде был комически неумелый программист, и все, что он делал, это жаловался на C #. Раньше мы шутили о выдуманном им языке под названием Crunk. Малоизвестный факт о Crunk, это первый язык, на котором компилятор также был написан на Crunk. :)
maple_shaft

2
Почему кто-то жаловался на C #? он никогда не использовал smalltalk или Lisp? LOL

2
возможный дубликат компилятора C и Денниса Ричи
vartec

4
@maple_shaft: быть справедливым, GCC компилятор написан на C . На самом деле это не проблема, если у вас есть хороший кросс-компилятор для компиляции первой версии. Первый компилятор C, конечно, должен был быть написан на другом языке.
Скотт Уитлок

Ответы:


89

Ха, я сделал это Многие процессоры имеют простые инструкции фиксированного размера длиной всего пару байтов. Для простого процессора, такого как, например, Motorola 6800, вы можете разместить все его инструкции на одном листе бумаги . С каждой инструкцией будет связан двухбайтовый код операции и аргументы. Вы можете вручную собрать программу, посмотрев код операции каждой инструкции. Затем вы пишете свою программу на бумаге , аннотируя каждую инструкцию соответствующим кодом операции. После того, как вы написали свою программу, вы можете последовательно записать каждый код операции в EPROMкоторый будет хранить вашу программу. Подключите СППЗУ к ЦП с помощью правильных инструкций по нужным адресам, и у вас будет простая рабочая программа. И чтобы ответить на ваш следующий вопрос, да. Это было больно (мы делали это в старшей школе). Но я должен сказать, что подключение каждой микросхемы в 8-битном компьютере и написание программы вручную дали мне глубокое понимание архитектуры компьютера, чего я, вероятно, не смог бы достичь каким-либо другим способом.

Более сложные микросхемы (например, x86) гораздо сложнее писать вручную, потому что они часто имеют инструкции переменной длины. Процессоры VLIW / EPIC, такие как Itanium , практически невозможно эффективно кодировать вручную, поскольку они работают с пакетами инструкций, которые оптимизируются и собираются передовыми компиляторами. Для новых архитектур программы почти всегда сначала пишутся и собираются на другом компьютере, а затем загружаются в новую архитектуру. Фактически, для таких фирм, как Intel, которые на самом деле создают процессоры, они могут запускать настоящие программы на архитектурах, которых еще нет, запуская их на симуляторах. Но я отвлекся ...

Что касается компиляторов, то, по сути, они могут быть немного больше, чем программы «вырезать и вставить». Вы можете написать очень простой, неоптимизирующий «язык высокого уровня», который просто объединяет простые инструкции на языке ассемблера без особых усилий.

Если вам нужна история компиляторов и языков программирования, я предлагаю вам ПОЛУЧИТЬ историю ФОРТРАНА .


27
, , , и это не должно быть "... Я предлагаю вам JMP для истории ..."
Binary Worrier

2
Мне очень очень очень жаль. Но я должен был. У меня только что был. к ...
Дэйв Маркл

9
@Dave: Ты понимаешь, что обречен на смерть велоцираптором ?
Двоичный беспорядок

7
Они «знали», потому что были буквально запрограммированы на выполнение этой операции, когда увидели сигнал 101010100 для данной инструкции. У них на самом деле есть встроенный модуль, отвечающий за инструкции по декодированию команд: en.wikipedia.org/wiki/Decoder
Дейв Маркл,

7
Стоит добавить: компилятор для нового языка, когда он написан на том же новом языке, иногда компилируется с помощью «прото-компилятора», написанного на другом языке, который создает наглядно правильный, но ужасно неэффективный код. После компиляции он запускается сам для создания достаточно быстрого компилятора. Сравните фон фон Неймана. : D
BMDan

54

Вот о чем говорит начальная загрузка компилятора (поскольку никто не упомянул, как она называется =).

процесс написания компилятора (или ассемблера) на целевом языке программирования, который он предназначен для компиляции. Применение этой методики приводит к самостоятельному компилятору.

Многие компиляторы для многих языков программирования загружаются, включая компиляторы для BASIC, ALGOL, C, Pascal, PL / I, Factor, Haskell, Modula-2, Oberon, OCaml, Common Lisp, Scheme, Java, Python, Scala и других .. ,

Проблема курицы и яйца

Если нужен компилятор для языка X, чтобы получить компилятор для языка X (который написан на языке X), как был написан первый компилятор? Возможные методы решения этой проблемы курицы или яйца включают в себя:

  • Реализация интерпретатора или компилятора для языка X на языке Y. Никлаус Вирт сообщил, что он написал первый компилятор Pascal на Фортране.
  • Другой интерпретатор или компилятор для X уже написан на другом языке Y; Вот как часто Схема загружается.
  • Более ранние версии компилятора были написаны в подмножестве X, для которого существовал какой-то другой компилятор; Вот как загружаются некоторые надмножества Java, Haskell и начальный компилятор Free Pascal.
  • Компилятор для X кросс-компилируется из другой архитектуры, где существует компилятор для X; именно так компиляторы для C обычно переносятся на другие платформы. Также этот метод используется для Free Pascal после начальной загрузки.
  • Написание компилятора на X; затем вручную скомпилировать его из исходного кода (скорее всего, неоптимизированным способом) и запустить его в коде, чтобы получить оптимизированный компилятор. Дональд Кнут использовал это для своей системы WEB-грамотного программирования ...

Хорошая ссылка, которая также приведет вас к en.wikipedia.org/wiki/History_of_compiler_writing . В общем, я думаю, что оригинальные компиляторы были написаны на ассемблере ( en.wikipedia.org/wiki/Assembly_language ). Лишь позже появилась идея самозагрузки или самостоятельного хостинга.
Майкл Леви

1
+1 НАКОНЕЦ! Странно, что это только третий самый высоко оцененный ответ. Да, начальная загрузка. Вот и ответ
Адам Ракис

15

В конечном итоге все компьютеры работают с двоичными кодами, которые загружаются в процессор. Эти двоичные коды совершенно естественны для процессора, но также совершенно бесполезны для людей. Одним из первых способов написания программы было пробивание отверстий в карточках. Положение отверстий представляло собой определенную позицию бита в слове, а наличие или отсутствие отверстия интерпретировалось как ноль или единица. Эти карты были помещены в правильную последовательность в коробке, а затем поданы в картридер, который эффективно преобразовывал их в двоичный код для процессора (и ваша жизнь была фактически потеряна, если вы уронили коробку).

Очевидно, что самые первые программисты обрабатывали двоичные коды один за другим и имели машину для перфорирования карт. По сути, это программирование на ассемблере на ваших руках и коленях. Когда у вас есть это, вы можете создать из него все остальное: простой текстовый редактор, компилятор языка ассемблера (для преобразования текстовых операторов сборки в двоичные коды), компоновщик и загрузчик. А в остальном, как говорится, уже история.


4
До появления карт у вас был набор переключателей для адреса, набор для слова данных и переключатель для загрузки данных. Вы запрограммировали каждый адрес памяти индивидуально, установив переключатели адреса и данных в двоичном представлении, и включили, а затем выключили переключатель нагрузки. Это заняло целую вечность, но программа состояла всего из нескольких слов, тогда байты еще не были изобретены.
uɐɪ

4
... А до этого пришлось его перепрограммировать . Веселье, веселье, веселье!
Майкл К

Да, но когда вам нужно было это сделать, это не совсем то, что мы думаем о современном компьютере, так как архитектура фон Неймана еще не была изобретена.
Дэйв Маркл

7

Небольшое приближение к рукам обнаруживает EDSAC Первоначальные заказы с конца 40-х годов. Поскольку это был первый ассемблер, он, вероятно, был написан на машинном языке.

Позже появились ассемблеры для других машин, таких как SOAP I и II для IBM 650. SOAP I, вероятно, также был написан на машинном языке, хотя я не нашел окончательного утверждения.

Чуть позже появился Фортран (переводчик формул) для IBM 704. Предположительно, он был написан на ассемблере для 704. Ранний ассемблер для 701 зачислен Натану Рочестеру .

Если вы хотите получить представление о том, как программировать компьютер на машинном языке, посетите один из моих любимых сайтов - компьютер-ретранслятор Гарри Портера .


Черт возьми, домашний компьютер Harry Porter (почти сказал Гарри Поттер) - УДИВИТЕЛЬНЫЙ. Хотелось бы, чтобы я понял, как что-то подобное было построено :(.

1
@Sauron: Гарри Портер не хотел бы ничего лучше, чем сказать вам. На этой странице у него есть красиво сделанный powerpoint, объясняющий все это. Это предполагает некоторые базовые знания схемотехники, но это не так уж сложно получить.
Майк Данлавей

Я знаю, что я просто месиво ^ _ ^, несмотря на то, что это очень впечатляющая машина, и я уверен, что в нее вложено много волшебных часов :).

6

Можно (если утомительно) написать прямой машинный код. Возможно, вы записываете программу на ассемблере на листе бумаги, а затем переводите ее вручную в инструкции с числовым машинным кодом, которые вводите в память машины. Вы даже можете пропустить шаг ассемблера на бумаге, если запомнили числовые значения всех инструкций машинного кода - не редкость в те дни, хотите верьте, хотите нет!

Самые первые компьютеры были напрямую запрограммированы в двоичном виде путем переключения физических переключателей. Это было большим улучшением производительности, когда аппаратное обеспечение развивалось, позволяя программисту (или помощнику по вводу данных) вводить код в шестнадцатеричных числах с клавиатуры!

Программный ассемблер стал актуальным только тогда, когда стало доступно больше памяти (поскольку ассемблерный код занимает больше места, чем необработанный машинный код), а аппаратное обеспечение развилось, чтобы позволить буквенно-цифровой ввод. Итак, первые ассемблеры были написаны непосредственно людьми, свободно владеющими машинным кодом.

Когда у вас есть ассемблер, вы можете написать компилятор для языка более высокого уровня в ассемблере.

История для 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, который является языком систем ближе к железу. Так что это не всегда языки более высокого уровня, реализованные в языках более низкого уровня, это также может быть наоборот.


3

Предполагая, что вы начинаете с простого набора инструкций и ничего более, вы начнете с создания минимального , едва функционального ассемблера или компилятора, который может загружать файл, анализировать минимальное подмножество целевого языка и генерировать исполняемый файл. файл в качестве вывода, написав необработанный машинный код с помощью шестнадцатеричного редактора или аналогичного.

Затем вы использовали бы этот едва функциональный компилятор или ассемблер для реализации немного более способного компилятора или ассемблера, который может распознавать большее подмножество целевого языка. Вспенить, промыть, повторить, пока не получится конечный продукт.


2

Это не так сложно, как кажется. В детстве;) Я сделал несколько разборок x86 в виду.

Вам даже не нужно учить это особенно. Это просто происходит, когда вы можете программировать на ASM, а затем пытаться исправить сторонний бинарный файл с помощью интерактивных дизассемблеров. Или при написании собственной защиты с шифрованием кода.

Т.е. иногда вы переходите даже с языка на коды, что неудивительно.


1

Первые компиляторы были реализованы с использованием ассемблера. И первые ассемблеры были реализованы путем кодирования программ в двоичном виде ...


Не так давно программирование в двоичном коде все еще было навыком, которым пользовались люди.

Когда я был студентом, я помню, как выполнял упражнение по программированию, которое подразумевало написание крошечной программы на машинном коде PDP-8 (я думаю), ввод ее через переключатели на передней панели и запуск ее. Спустя пару лет я купил себе комплект для разработки системы 6502 с шестигранной клавиатурой для ввода программ ... и 4 КБ ОЗУ.


-3

ОЧЕНЬ ПРОСТОЙ ОТВЕТ. Предположим, мы пишем аппаратную программу и сохраняем ее в ПЗУ. Это можно рассматривать как компилятор. Поэтому я просто хочу сказать, что самый первый компилятор был аппаратным. По мере совершенствования технологии эти простые компиляторы затем использовались для написания компиляторов высокого уровня.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.