Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
KursPr.DOC
Скачиваний:
1
Добавлен:
15.09.2019
Размер:
322.56 Кб
Скачать

4 Алгоритм работы

Фактически алгоритм работы данного компилятора можно разбить на два этапа, что обусловлено особенностями компилятора. Для большей гибкости кроссассемблера была введена реляционная база данных, в которой хранятся форматы команд, правила записи и макросы. Это позволяет полностью контролировать команды и макросы, форматы их записи, т. е. редактировать их. Данная структура позволяет вносить изменения не только в имени команды, но и в значениях, которые принимает данная команда. База данных условно разделена на две части: первая – таблица, которая хранит описания макросов; вторая – таблица, хранящая имена команд и описания. Для простоты реализации, а также для убодства хранения, была выбрана система управления базами данных Microsoft Access. Таким образо все реализованные таблицы хранятся в одном единственном файле, что упрощает ее использование.

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

4.1 База данных команд и макросов

Предварительно необходимо рассмотреть состав и организацию базы данных, которой хранятся команды их описания и макросы.

Выше уже упомянуто, что сама база данных условно разделена две части, первая из которых хранит макросы, а вторая является хранилищем для команд и их описания. Часть, хранящая макросы представляет из себя таблицу, которая состоит из 3-х полей:

Таблица 4.1.1 Структура таблицы «Макросы»

Счетчик

Имя макроса

Тело макроса

В таблице 4.1.1 «Макросы» представлены следующие поля: поле «счетчик» представляет собой ключевое внутреннее поле, которое фактически не используется в момент компиляции, Поле «Имя макроса» хранит имя макроса, а поле «Тело макроса» является контейнером для тела макроса, и используется в момент компиляции, при создании оптимального кода.

Вторая часть имеет более сложную структуру, так как содержит уже две связанные таблицы, которые представлены ниже

Таблицы 4.1.2 Структура таблицы «Команда»

Счетчик

Имя команды

НАК

Таблицы 4.1.3 Структура таблицы «Связи»

Счетчик

Имя команды

Атрибут

Сещение

В таблице 4.1.2 представлена структура, которая хранит имя команды в поле «Имя команды» и начальный адрес команды в поле «НАК». Больший интерес представлят собой поле «НАК», которое содержит начальное значение, которое принимает данная команда. К примеру команда mov имеет несколько вариантов реализации: mov R1,R2 или mov R1,A и т. д., таким образом в таблице команд существует несколько вариантов записи. В данной реализации выделяется одна команда mov и ее начальное значение «0000000». Следующая таблица 4.1.3 хранит расширение команд представленных в предыдущей таблице. Они свзаны между собой по полю [команды].[Имякоманды] - [Расширение].[Имя команды]. Далее по атрибуту связи находится смещение, соответствующее данному варианту команды, что в результате представляет собой готовую команду. В результате анализа все используемых команд введены следующие атрибуты, представленные в таблице 4.1.4.

Таблица 4.1.4 Таблица атрибутов команд.

Номер

атрибут

0

1

R1, R2

2

R2, R1

3

A, value

4

R1, A

5

R2, A

6

A, R1

7

A, R2

8

A, [adress]

9

[adress], A

10

R1, value

11

R2, value

12

R1

13

R2

14

[address]

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

4.2 Алгоритм загрузки компилятора.

Такая организация базы данных компилятора позволяет производить прямой доступ ко всем элементам базы данных, но на это тратится определенное время. А с учетом того, что работа с базой данных осуществляется через специальный драйвер операционной системы, работа которого также занимает определенное время. Таким образом, общее время компиляции занимает уже достаточно большое время. Во избежании этого было принято решение поместить структуру команд в оперативную память, тем более их количество не велико. Для реализации данной структуры в оперативной памяти используется дерево, в корневой вершине которого храниться точка входа, а во всех остальных храняться буквы, составляющие команды, а ребра данного дерева отражают связи между букв, т. е. порядок их следования в слове. Листья дерева содержат ссылки на начальное значение команды (она может иметь несколько враиантов записи), которое в свою очередь ссылается на список атрибутов со смещением (см. рис. 4.2.1).

Точка входа

M

O

V

НАК

C

A

D

D

N

D

A

J

B

C

Рисунок 4.2.1 Пример дерева команд.

На рисунке 4.2.1 изображена схема дерева, поясняющего его структуру. Разбор базы данных и занесение в дерево осуществляется только для команд, а работа с макросами осуществляется непосредственно из базы данных, так как тело макроса может быть большого размера.

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

  1. Загрузка оболочки – программы компилятора.

    1. Подключение основных модулей;

    2. Подключение драйверов работы с базами данных;

    3. Обработка информации о базе данных в реестре.

  2. Открытие базы данных.

  3. Загрузка информации из базы данных:

3.1 Устанавливаем счетчики таблиц «Команды» и «Расщирения» в начальную отметку;

    1. Читаем из таблицы «Команды» запись, соответствующую счетчику, из столбца «Имя команды» имя первой команды во временную строку, устанавливаем счетчик строки в 0;

    2. Считываем символ из строки относительно счетчика не нулевой, то сопоставлям с деревом иначе переходим дальше к 3.4:

Если первый от точки входа символ уже существует и совпадает с прочитанным символом, то наращивам счетчик строки на 1 и возвращаемся к шагу 3.3.

Если первый символ от точки входа не совпадает с прочитанным, то делаем новую вершину, записываем туда символ, переходм к шагу 3.3.

    1. Прочитанный символ равен 0, т. е. воманда окончена, делаем ссылку на сруктуру, в которой будет храниться начальное значение данной команды из поля «НАК»;

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

    3. Со структуры, в которой храниться начальное значение команды делаем ссылку на структуру атриьутов и смещений, и переносим данные из временной структуры в текущую;

    4. Наращиваем счетчик таблицы «Комнады», и, если он не привышает количество команд, переходим к шагу 3.2.

4. Завершаем работу зугрузки, созданием структуры, которая хранит имена макросов.

Алгоритм загрузки прост и не имеет никаких программных особенностей. Единственная проблема, возникающая при работе данного проекта – это работа с базой данных, так как она должна быть прописана в системном реестре операционной системы, потому что использует стандартные драйвера ODBC.

4.3 Алгоритм компиляции.

Алгоритм процесса компиляции немного сложнее, чем предыдуший алгоритм загрузки компилятора. Для простоты был реализован однопроходный просмотр. Такая схема реализована с учетом того, что каждая строка будет отдельно оптимизироваться и разбираться анализаторами, а так же провоизводится генерация объектного кода. Алгоритм имеет вид:

  1. Загрузка исходного кода программы.

  2. Установка счетчика указателя прочианной строки в начальное положение.

  3. Чтение строки соответствующей счетчику-указателю во временную строковую переменую.

  4. Удаление избыточных символов табуляции (пробелов, табуляций и др.) и установка счетчика строки в начальное положение.

  5. Чтение символа со строки и сопоставление с деревом начиная спервого уровня вглубь: Если символ совпадает с одним из символов, находящихся вершинах дерева команд на первом уровне, то наращиваем счетчик строки на 1 и переходм к шагу 5. Если символ не совпадает ни с одни из находящихся на первом уровне символов, то записываем его в структуру меток, возвращаемся а шаг 5. Если на каком-то i-ом шаге прочитанный символ не нашел отображения, а предыдущие существовали, то переписываем этот и все предыдущие в стуктуру меток, возвращаемся на шаг 5. Если в строке найден пробел или двоеточие, переходим к шагу 6.

  6. Анализ полученного слова. Если данное слово было записано в структуру меток и на шаге 5 встретилось двоеточие производим генрацию кода соотвествующего данной метке, иначе выдать информацию об ошибке. Если данное слово была команда и найден пробел производим чтение последующих символов и если он идентична одному из допустимых атрибутов данной команды, то произвести генерацию объектного кода, иначе выдать информацию об ошибке.

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

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

ВЫВОДЫ

В результате работы были реализованы кроссассемблер для преобразования ассемблерного кода в объектный, реализующий связывание объектных файлов и таким образом создания исполняемого кода.

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

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

СПИСОК ИСПОЛЬЗОВАННОЙ ЛИТЕРАТУРЫ

  1. Использование Turbo Assembler при разработке программ / Сост. А. А. Чекатов. - Киев: “Диалектика”, 1995. - 288 с.

  2. Сван Т. Освоение Turbo Assembler.- К.: “Диалектика”, 1996. - 544с., ил.

  3. Дж. Донован Системное программирование, пер. с англ., Л.Д. Райкова -, “Мир”, М - 1975, стр. 540.

  4. Грегори Кейт. Использование Visual C++ 6. Специальное издание.: Пер. с англ. – М.;СПб.;К.:Издательский дом «Вильямс»,1999. – 864с.: ил. – Парал. тит. англ., уч. пос.

  5. Конспект лекций по дисциплине «Системное программирование».

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]