Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛАБОРАТОРНА РОБОТА № 4.doc
Скачиваний:
3
Добавлен:
09.11.2019
Размер:
358.91 Кб
Скачать

Побудова асемблерного коду по дереву виводу

Як мова асемблера візьмемо мову асемблера процесорів типу Intel 80x86. При цьому вважатимемо, що операнди можуть бути поміщені в 16-розрядні регістри процесора і в коді результуючої об'єктної програми можуть використовуватися регістри AX (акумулятор) і DX (регістр даних), а також стік для зберігання проміжних результатів.

Тоді чотирьом формам поточного вузла дерева відповідатимуть наступні фрагменти коди на мові асемблера (табл. 5):

Таблиця 5.

Перетворення типових вузлів дерева виводу в код на мові асемблера

Вид вузла дерева

Результуючий код

Примітка

mov ax,oper1

act ax,oper2

act - команда відповідної операції

oper1,oper2 - операнди (листя дерева)

Code(Узел 2)

mov dx,ax

mov ax,oper1

act ax,dx

Узел 2 - вузол (не лист!) дерева, що пролягає нижче

Code(Узел 2) - код, що створюються процедурою для вузла, що пролягає нижче

Code(Узел 2)

act ax,oper2

Code(Узел 2) - код, що створюються процедурою для вузла, що пролягає нижче

Code(Узел 2)

push ax

Code(Узел 3)

mov dx,ax

pop ax

act ax,dx

Code(Узел 2) - код, що створюються процедурою для вузла, що пролягає нижче

Code(Узел 3) - код, що створюються процедурою для вузла, що пролягає нижче

push і pop - команди збереження результатів в стеку і витягання результатів із

Розглянемо приклад дерева виводу для виразу A := B*c + D - B*10 на мал. 5 і відповідний йому фрагмент коди на мові асемблера, побудований по описаних вище правилах (звернете увагу, що для операції привласнення використовується окремий код, що не підпадає під загальні правила):

Мал. 5. Дерево виводу для арифметичного

виразу.

Крок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,B

mul ax,C

add ax,D

push ax

Code(U5)

mov dx,ax

pop ax

sub ax,dx

mov A,ax ; операція привласнення

Крок 5: mov ax,B

mul ax,C

add ax,D

push ax

mov ax,B

mul ax,10

mov dx,ax

pop ax

sub ax,dx

mov A,ax ; операція привласнення

Отриманий об'єктний код на мові асемблера, очевидно, може бути оптимізований, проте для його обробки потрібні спеціальні (орієнтовані саме на дану мову асемблера) методи і структури, що враховують взаємозв'язок операцій. Крім того, орієнтація на певну мову асемблера зводить нанівець універсальність методу. Так в приведеному прикладі використовується команда mul, яка в ранніх версіях процесорів фірми Intel має обмеження на типи операндів, а отже, в універсальному компіляторі не може бути використана так, як в даному прикладі. Це зажадає, щоб генерація коди для вузлів дерева йшла в залежності не тільки від операндів, але і від типу операції (навіть у приведеному прикладі таку залежність довелося встановити для операції привласнення).

Зазвичай такі проблеми вирішуються таким чином, що замість команд безпосередньо мови асемблера використовуються команди деякого близького до нього проміжного псевдокоду. Більшість цих команд один в один відображаються потім в команди мови асемблера, інші ж однозначно перетворяться у фіксовану послідовність команд.