Скачиваний:
10
Добавлен:
01.05.2014
Размер:
159.74 Кб
Скачать
  1. Преобразование полиз в язык ассемблера

    1. Введение

В качестве языка ассемблера будет использован 32-битный MicrosoftMacroAssembler, версии 6.14. Порождаемые исполняемые файлы будут 32-битными консольными приложениями дляMicrosoftWindows.

Такой выбор обоснован тем, что большинство современных программ являются 32-битными и написаны для операционной системы MicrosoftWindows, в то время как программы дляDOSперестают поддерживаться.

    1. Входные данные

После описанного ранее этапа трансляции языка в ПОЛИЗ, мы получаем набор данных, который будет использоваться на этапе преобразования ПОЛИЗ в язык ассемблера. Напомним, что это за данные:

  • Таблица типов – таблица, содержащая исчерпывающую информацию обо всех используемых в программе типах данных.

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

  • Таблица меток – таблица, содержащая имена всех меток в программе.

  • Программа, транслированная в ПОЛИЗ – текстовый файл, содержащий операнды и команды ПОЛИЗ.

    1. Модель исполнения полиз

Простейшей моделью для исполнения программы в ПОЛИЗ является стек.

Программа в ПОЛИЗ предполагает четыре вида элементов:

  • именованная переменная или константа (например, x)

  • число, например (например, 10)

  • метка (например, :lab1)

  • команда (например,@SET)

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

Рассмотрим пример:

a

30

@SUBINT

В данном случае, мы встречаем aи кладем его в стек. Затем, встречаем 30 и кладем его в стек. Затем встречаем команду сложения целых чисел @SUBINT, которая работает со стеком следующим образом – она вынимает из него два элемента, производит над ними операцию сложения и кладет результат обратно в стек.

Таким образом, при переводе в язык ассемблера, нашей главной задачей будет реализация стековой машины, эмулирующей исполнение ПОЛИЗ.

Перевод таблицы переменных в сегмент данных ассемблера

Прежде всего, рассмотрим, во что будут транслированы данные. Предположим, что в программе на исходном языке мы имели объявление такого вида:

...

var

a : type1;

b : type2;

...

После трансляции в ПОЛИЗ мы кроме текста транслированной программы получаем также несколько таблиц – таблицу переменных, таблицу типов и таблицу меток. Таблица переменных и таблица типов представляют собой полное описание всех используемых в программе переменных. Эти переменные необходимо поместить в сегмент данных в ассемблере.

Сгенерированный сегмент данных для приведенного примера будет выглядеть так:

...

_data segment

__variable_a <описание специфичное для типа type1>

__variable_b <описание специфичное для типа type2>

_data ends

...

Имена для переменных в сегменте данных соответствуют именам в таблице переменных, но к ним добавляется префикс __variable_, это делается затем, чтобы избежать возможных конфликтов имен с командами ассемблера.

В зависимости от типа данных могут порождаться различные описания переменной.

  1. Для переменной целочисленного типа (integer) описание будет выглядеть так:

__variable_a dd 01h dup (0)

То есть целочисленная переменная представляет собой знаковое двойное слово (4 байта), изначально инициализированное значением 0.

  1. Аналогично, для переменной рационального типа (rational):

__variable_a dd 00h, 01h

То есть рациональная переменная представляет собой два подряд идущих знаковых двойных слова (8 байт), причем первое двойное слово соответствует числителю дроби, а второе – знаменателю дроби, таким образом рациональная переменная инициализируется значением дроби 0/1.

  1. Переменные типа-диапазона и перечислимого типа транслируются таким же образом, как и переменные целочисленного типа. Таким образом логический тип (boolean) является частным случаем перечислимого типа и, поэтому занимает 4 байта.

  1. Переменные, являющиеся массивами рациональных чисел транслируются следующим образом:

__variable_a dd <количество элементов в массиве> dup (0, 1)

При таком объявлении каждый элемент массива инициализируется в значение дроби 0/1. Многомерные массивы приводятся к одномерным массивам с аналогичным количеством элементов.

  1. Все остальные переменные-массивы транслируются в:

__variable_a db <размер массива в байтах> dup (0)

Соседние файлы в папке Бяша