13_Схема работы транслятора с языка Ассемблер (В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования)
Описание файла
Файл "13_Схема работы транслятора с языка Ассемблер" внутри архива находится в папке "В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования". PDF-файл из архива "В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования", который расположен в категории "". Всё это находится в предмете "практика расчётов на пэвм" из 1 семестр, которые можно найти в файловом архиве МГУ им. Ломоносова. Не смотря на прямую связь этого архива с МГУ им. Ломоносова, его также можно найти и в других разделах. .
Просмотр PDF-файла онлайн
Текст из PDF
Глава 13. Схема работы транслятора с языка АссемблераСейчас мы рассмотрим, как транслятор преобразует входной модуль на "чистом" языке Ассемблера (уже без макросредств, которые обработал Макропроцессор) в объектный модуль.1 Разумеется,мы изучим только общую схему этого достаточно сложного процесса. Наша цель – рассмотреть основные принципы работы транслятора с языка Ассемблера и ввести необходимую терминологию, атакже снять тот покров таинственности с работы программы-переводчика, который может быть у некоторых читателей.
Более подробно этот вопрос, который относится к большой теме "Формальныеграмматики и методы компиляции", изучается в другом курсе.Итак, как мы знаем, Ассемблер относится к классу системных программ, которые называютсятрансляторами2 – переводчиками с одного алгоритмического языка на другой. Наш транслятор является компилятором, он переводит модуль с языка Ассемблера на объектный язык. При трансляциивыполняются следующие шаги.•Анализ входного модуля на наличие синтаксических ошибок.•Выдача протокола работы компилятора – так называемого листинга, а также выдачу аварийных сообщений об ошибках. Выдачу листинга при желании, как правило, можно заблокировать.•Генерация объектного модуля.Разберём более подробно первый этап – анализ программы на наличие ошибок.
Ясно, что найтивсе ошибки можно, только просмотрев весь текст модуля, строка за строкой. Каждый просмотр текста программного модуля компилятором называется проходом. Наш компилятор с Ассемблера просматривает программу дважды, т.е. совершает два прохода. Такие компиляторы называются двухпроходными. Двухпроходная схема трансляции наиболее простая для реализации, можно, однако,усложнив алгоритм, производить трансляцию и за один проход (например, так работает транслятор сязыка Турбо-Паскаль).3На первом проходе транслятор с Ассемблера, анализируя текст программы, находит многие (ноне все) ошибки, и строит некоторые важные таблицы, данные из которых используются далее как напервом, так и на втором проходе.
Вкратце алгоритм первого прохода состоит в следующем. Так какосновной синтаксической единицей нашего языка является предложение Ассемблера, то рассмотрим, как происходит обработка предложений на первом проходе.Сначала каждое предложение Ассемблера обрабатывается специальной программой транслятора,которая называется лексическим анализатором. Она разбивает каждое предложение программы налексемы – логически неделимые единицы языка. О лексемах мы уже должны немного знать из изучения языка Паскаль. Как и в Паскале, в языке Ассемблера существуют следующие классы лексем.•Имена. Как и в Паскале, это ограниченные последовательности букв и цифр, начинающиесяс буквы, при этом большие и маленькие буквы не различаются.
Как мы помним, в Паскалек буквам относился также и символ подчёркивания, а в Ассемблере к буквам относятся итакие символы, как вопросительный знак, точка (правда, только в первой позиции и у служебных имён) и некоторые другие символы. Все имена Ассемблера делятся на служебныеи имена пользователя. В отличие от Паскаля, в Ассемблере нет стандартных имён (на-1Вообще говоря, как мы уже говорили ранее, на самом деле Макропроцессор и Ассемблер обрабатываютпрограмму одновременно, предложение за предложением.
Как мы вскоре узнаем, первыми каждое предложение обрабатывают специальные программы Ассемблера, которые называются лексическим и синтаксическиманализаторами, а затем, если нужно, это предложение обрабатывает Макропроцессор. Однако конечный этапкомпиляции – генерация объектного модуля – выполняется Ассемблером уже после полного завершения работы Макропроцессора.2Термин транслятор обозначает программу-переводчика с одного (формального) языка на другой. Трансляторы делятся на компиляторы, которые переводят программу целиком, и интерпретаторы, которые выполняют построчный перевод и исполнение каждой переведённой строки программы. Хорошим аналогом являетсяписьменный (всего текста) и устный (синхронный, по одному предложению) перевод с одного языка на другой.В английском языке для этих действий служат два разных глагола: translate и interpret.3В основном это можно сделать потому, что в Паскале практически всегда имя пользователя описываетсяили объявляется перед его первым использованием в программе.2помним, что стандартное имя имело заранее определённый смысл, но эти имена в Паскалепрограммисту можно было переопределить).•Числа.
Язык Ассемблера, как и Турбо-Паскаль, допускает запись чисел в различных системах счисления (десятичной, двоичной, шестнадцатеричной и некоторых других). Не надозабывать и о вещественных числах.•Строки символов. Строки символов в Ассемблере ограничены либо апострофами, либодвойными кавычками. Исключением является строка-параметр директивы эквивалентности,например, X equ ABC++ . Напомним, что выполнение этой директивы требует замены вовсех следующих предложениях имени X на строку символов ABC++.
После такой заменыобычно требуется повторное разбиение строки на лексемы. Кроме того, ещё раз напомним,что в нашем упрощённом изложении алгоритма работы компилятора мы считаем, что Макропроцессор, который рассматривал фактические параметры макрокоманд тоже как строкисимволов, ограниченных запятыми, пробелами или точкой с запятой, уже закончил своюработу.•Разделители. Как и в Паскале, лексемы перечисленных выше классов не могут располагаться в тексте программы подряд, легко понять, что между ними обязательно должна находиться хотя бы одна лексема-разделитель.
К разделителям относятся знаки арифметическихопераций, почти все знаки препинания, пробел и некоторые другие символы.•Комментарии. Эти лексемы не влияют на выполнение алгоритма, заложенного в программу,они переносятся в листинг, а из анализируемого текста удаляются. Не являются исключением макрокомментарии, которые начинаются с двух символов ';;', как мы знаем, такиекомментарии не переносятся в макрорасширения и попадают в листинг программы в одномэкземпляре (т.е. только внутри макроопределений).В качестве примера ниже показано предложение Ассемблера,Metka: mov ax,Mas+67[bx]; Комментарийкаждая лексема в нём выделена в прямоугольник, обратите внимание на лексему-пробел между кодом операции mov и первым операндом ax:Metka : movax , Mas + 67 [ bx ] ; КомментарийНа этапе лексического анализа выявляются лексические ошибки, когда некоторая группа символов не может быть отнесена ни к одному из классов лексем.
Примеры лексических ошибок:1134X'A'38B"CВсе опознанные (правильные) лексемы записываются на первом проходе в специальную таблицу лексем. В этой таблице вместе с каждой лексемой указывается её класс и некоторые другие атрибуты. Это делается в основном для того, чтобы на втором проходе транслятор мог уже двигаться попрограмме по лексемам, а не по отдельным составляющим их символам, что позволяет существенноускорить второй просмотр текста модуля.После разбиения предложения Ассемблера на лексемы начинается второй этап обработки предложения – этап синтаксического анализа. Этот этап выполняет программа транслятора, котораяназывается синтаксическим анализатором.
Алгоритмы синтаксического анализа могут быть весьма сложны, и здесь мы не будем их подробно рассматривать, это, как уже упоминалось, тема отдельного курса. Если говорить совсем коротко, то синтаксический анализатор пытается из лексем построить более сложные конструкции предложения: поля метки, кода операции и операндов. Особое внимание на этом этапе уделяется в программе именам пользователя, они заносятся синтаксическим анализатором в специальную таблицу имён. Вместе с каждым именем в эту таблицу заносятся и атрибуты (свойства) имени.
Всего в Ассемблере у имени пользователя различают четыре основные атрибута, ниже перечислены эти атрибуты (сразу отметим, что не у каждого имени есть все из них). Дляудобства дальнейшего изложения этим четырём атрибутам присвоены имена Segment, Offset,Type и Value.1Здесь надо сказать, что компилятор с Ассемблера не предполагает глубокого знания программистом теории компиляции, поэтому в листинге программы такие ошибки называются общим термином "синтаксическиеошибки", хотя, как мы узнаем немного позже, "настоящие" синтаксические ошибки определяются другой частью компилятора – синтаксическим анализатором.3•Атрибут сегмента Segment. Этот атрибут имеет формат i16, он задаёт адрес начала (делённый на 16) того сегмента, в котором описано или объявлено данное имя.1•Атрибут смещения Offset, он также имеет формат i16 и задаёт смещение расположения имени от начала того сегмента, в котором оно описано.
Атрибуты Segment и Offsetмогут иметь только имена, определяющие области памяти и метки команд.•Атрибут типа Type. С этим атрибутом имени мы уже знакомы, для имён переменных онравен длине переменной в байтах, а для меток равен near=–1 и far=–2 для близкой идальней (в другом модуле)2 метки соответственно. Все остальные имена имеют тип ноль (внекоторых учебниках по Ассемблеру это трактуется как отсутствие типа, при этом говорится, что у таких имён атрибута Type нет, однако операция Ассемблера type выдаёт длятаких имён значение ноль).•Атрибут значения Value.
Этот атрибут определён только для имён сегментов, а также дляимён числовых констант и числовых переменных периода генерации.Приведём примеры описаний имён, которые имеют первые три из перечисленных выше атрибутов:Adb13; Не имеет атрибута Value !Bequ AC:mov B,1Dequ CА теперь примеры имён, у которых есть только атрибут Value (и атрибут Type=0):Nequ 100; Value=100Mequ N+1; Value=101K=13;Value=13Value=13Pequ K;Data segment;Value=DataРассмотрим теперь пример маленького, синтаксически правильного, но, вообще говоря, бессмысленного (не головного) программного модуля на Ассемблере, для этого модуля мы построимтаблицу имён пользователя:Data segmentAdw19Bdb?Data endsCode segmentassume cs:Code,ds:Dataextrn X:farmovax,Datamovcx,RjmpLRequ-14call XL:retCode endsendНа рис.