Россия, Челябинск, Южно-Уральский Государственный Университет (НИУ) |
Основы компиляторов
Объектная программа
Объектная программа может быть
- последовательностью абсолютных машинных команд
- последовательностью перемещаемых машинных команд
- программой на языке ассемблера
- программой на некотором другом языке
Наиболее эффективным методом с точки зрения скорости компиляции является отображение исходной программы в абсолютную программу на машинном языке, пригодную для непосредственного исполнения. Такой тип компиляции больше всего подходит для небольших программ, не использующих независимо компилируемых подпрограмм.
Однако для более сложных программ необходимо создавать объектные программы в форме последовательности перемещаемых машинных команд. Перемещаемая машинная команда представляет собой команду, в которой адресация ячеек памяти производится относительно некоторого подвижного начала. Объектную программу называют также перемещаемым объектным сегментом. Этот сегмент может быть связан с другими сегментами, такими, как независимо компилируемые подпрограммы пользователя, подпрограммы ввода-вывода и библиотечные функции.
Такое связывание (создание единого перемещаемого объектного сегмента из набора различных сегментов) осуществляется программой, которая называется редактором связей. Далее единый перемещаемый объектный сегмент или модуль загрузки размещается в памяти программой, называемой загрузчиком, которая превращает перемещаемые адреса в абсолютные. После этого программа готова к выполнению.
Трансляция в ассемблер
Трансляция программы в ассемблер несколько упрощает конструирование компилятора. Однако, такой подход удлиняет технологическую цепочку выполнения программы, так как объектная программа, порожденная компилятором, должна быть впоследствии обработана ассемблером, а также редактором связей и загрузчиком.
У трансляции в ассемблер есть несколько ощутимых преимуществ:
- уровень ассемблера все-таки выше, чем у машинного кода; поэтому при трансляции в ассемблер программисту не приходится возиться с некоторыми утомительными техническими деталями, например, ассемблер берет на себя разрешение операторов безусловного перехода на еще неопределенные метки (переходы вперед), распределение памяти под данные, расчет длин переходов и т.п.
- использование ассемблера позволяет отследить целый ряд ошибок, которые могут возникнуть при генерации кода (например, неправильная мнемоника команды); при генерации в машинные коды отловить такие ошибки значительно труднее
- порождаемый текст на ассемблере значительно читабельней, чем машинный код; это может помочь при отладке компилятора.
При генерации кода для платформы .NET у нас, в сущности, и нет никаких других возможностей, так как MSIL представляет собой высокоуровневый ассемблер, максимально абстрагированный от конкретных целевых платформ.
T-диаграммы
Мы обозначили компилятор, переводящий цепочки языка в цепочки языка
и написанный на языке
, следующим образом:
. Для представления компилятора мы можем использовать также так называемые Т-диаграммы:
Компилятор, переводящий язык L в язык ассемблера A и написанный на языке A можно представить следующими способами: или
Т-диаграммы достаточно удобны при обсуждении различных способов получения компиляторов.