Преобразование дерева операций в код на языке ассемблера
В качестве языка ассемблера возьмем язык ассемблера процессоров типа Intel 80x86. При этом будем считать, что операнды могут быть помещены в 16-разрядные регистры процессора и в коде результирующей объектной программы могут использоваться регистры АХ (аккумулятор) и DX (регистр данных), а также стек для хранения промежуточных результатов.
Функцию, реализующую перевод узла дерева в последовательность команд ассемблера, назовем Code. Входными данными функции должна быть информация об узле дерева операций. В ее реализации на каком-либо языке программирования эти данные можно представить в виде указателя на соответствующий узел дерева операций. Выходными данными является последовательность команд языка ассемблера. Будем считать, что она передается в виде строки, возвращаемой в качестве результата функции.
Тогда четырём формам текущего узла дерева для каждой арифметической операции будут соответствовать фрагменты кода на языке ассемблера, приведенные в табл. 4.7.3.
Каждой допустимой арифметической операции будет соответствовать своя команда на языке ассемблера. Если взять в качестве примера операции сложения (+), вычитания (-), умножения (*) и деления (/), то им будут соответствовать команды add, sub, mul и div. Причем в ассемблере Intel 80x86 от типа операции зависит не только тип, но и синтаксис команды (операции mul и div в качестве первого операнда всегда предполагают регистр процессора АХ, который не нужно указывать в команде). Соответствующая команда должна записываться вместо act при порождении кода в зависимости от типа узла дерева.
Таблица 4.5 - Преобразование узлов дерева вывода в код на языке ассемблера для арифметических операций
Вид узла дерева | Результирующий код | Примечание | |||
| mov ax, operl act ax, oper2 | act — команда соответствующей операции operl, oper2 — операнды (листья дерева) | |||
| Code (Узел 2) mov dx, ax mov ax, operl act ax, dx | Узел 2 -нижележащий узел (не лист!) дерева Code (Узел 2) -код, порождаемый процедурой для нижележащего узла | |||
| Code (Узел 2) act ax, орег2 | Code (Узел 2) — код, порождаемый процедурой для нижележащего узла | |||
| Code (Узел 2) push ax Code (УзелЗ) mov dx, ax pop ax act ax, dx | Code (Узел 2) — код, порождаемый процедурой для нижележащего узла Code (Узел 3) -- код, порождаемый процедурой для нижележащего узла push и pop — команду сохранения результатов в стеке и извлечения результатов из стека |
Код, порождаемый для операции присвоения результата, будет отличаться от кода, порождаемого для арифметических операций. Кроме того, семантика языка требует, чтобы в левой части операции присвоения всегда был операнд, поэтому для нее возможны только два типа узлов дерева, влекущие порождение кода(два других типа узлов должны приводить к сообщению об ошибке, которая в компиляторе обнаруживается синтаксическим анализатором). Фрагменты кода для этой операции приведены ниже в таблице 4.6.
Таблица 4.6 - Преобразование узлов дерева вывода в код на языке ассемблера для операции присвоения
Вид узла дерева | Результирующий код | Примечание | |||
| mov ax, орег2 mov operl, ax | operl, oper2 — операнды (листья дерева) | |||
| Code (Узел 2) mov operl, ax | Узел 2 — нижележащий узел (не лист!) дерева Code (Узел 2)-код, порождаемый процедурой для нижележащего узла |
Теперь последовательность порождаемого кода определена для всех возможных типов узлов дерева»
Рассмотрим в качестве примера выражение A:-B*C+D-B*10. Соответствующее ему дерево вывода приведено на рис. 4.7.
Рисунок 4.7 Дерево операций для арифметического
выражения «A:=B*C+D-B*10»
Построим последовательность команд языка ассемблера, соответствующую дереву операций на рис. 4.7. Согласно принципу СУ-перевода, построение начинается от корня дерева. Для удобства иллюстрации рекурсивного построения последовательности команд все узлы дерева помечены от U1 до U5. Рассмотрим последовательность построения цепочки команд языка ассемблера по шагам рекурсии. Эта последовательность приведена ниже.
Шаг 1.
Code(U2)
mov A, ax
Шаг 2.
Code(U3)
push ax
Code(U5)
mov dx, ax
pop ax
sub ax, dx
mov A, ax
Шаг 3.
Code(U4)
add ax, D
push ax
Code(U5)
mov dx, ax
pop ax
sub ax, dx
mov A, ax
Шаг 4.
mov ax, В
mul С
add ax, D
push ax
Code(U5)
mov dx, ax
pop ax
sub ax, dx
mov A, ax
Шаг 5.
mov ax, В
mul С
add ax, D
push ax
mov ax, В
mul 10
mov dx, ax
pop ax
sub ax, dx
mov A, ax
Оптимизация кода
Дата добавления: 2016-03-27; просмотров: 796;