Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
spo_otchet_chumak.doc
Скачиваний:
6
Добавлен:
01.04.2025
Размер:
206.85 Кб
Скачать

Лабораторная работа №11 Генерация кода на ассемблере для арифметического выражения

1)Цель работы: Модифицировать «программу-калькулятор», созданную в прошлой лабораторной работе так, чтобы вместо в качестве семантических действий было не прямое вычисление результата, а генерация кода на ассемблере, с помощью которого после компиляции и компоновки новой программы, можно будет получить результат.

Изменим процедуры обработки арифметического выражения следующим образом:

procedure tt;

begin

ff;

scan1(t,n);

while not(((t='r')and((n=7)or(n=10)or(n=11)or(n=17)or(n=9)or(n=14)or(n=15)or(n=5)or(n=3)))or((t='R')and((n=4)or(n=5)or(n=6)))) do

begin

scan(t,n);

if (t='r') then

case n of

12: begin

ff;

writeln(final,'pop bx');

writeln(final,'pop ax');

writeln(final,'mul bx');

writeln(final,'push ax');

end;

13: begin

ff;

writeln(final,'pop bx');

writeln(final,'pop ax');

writeln(final,'div bx');

writeln(final,'push ax');

end;

else begin

err('ожидалось арифметическое действие');

end;

end

else err(' ожидалось арифметическое действие ');

scan1(t,n);

end;

end;

procedure ee;

begin

tt;

scan1(t,n);

while not(((t='r')and((n=7)or(n=17)or(n=9)or(n=14)or(n=15)or(n=5)or(n=3)))or((t='R')and((n=4)or(n=5)or(n=6)))) do

begin

scan(t,n);

if (t='r') then

case n of

10: begin

tt;

writeln(final,'pop bx');

writeln(final,'pop ax');

writeln(final,'add ax,bx');

writeln(final,'push ax');

end;

11: begin

tt;

writeln(final,'pop bx');

writeln(final,'pop ax');

writeln(final,'sub ax,bx');

writeln(final,'push ax');

end;

else begin

err(ожидалось арифметическое действие ');

end;

end

else err(ожидалось арифметическое действие ');

scan1(t,n);

end;

end;

procedure ff;

var temps:string;

k:integer;

begin

scan(t,n);

case t of

'c': begin

writeln(final,'mov ax,',sl);

writeln(final,'push ax');

end;

'i': begin

writeln(final,'mov ax,',sl);

writeln(final,'push ax');

end;

'r': begin

if (n=6) then

begin

ee;

scan(t,n);

if not ((t='r')and(n=7)) then err('ожидалась закрывающая скобка');

end

else err('ожидалась открывающая скобка')

end

else err('неожиданный символ');

end;

end;

Также изменим главный метод программы:

begin

prepare;

writeln(final,'.model tiny');

writeln(final,'.code');

writeln(final,'.386');

writeln(final,'org 100h');

writeln(final,'start:');

ee;

writeln(final,'pop ax');

writeln(final,'mov bx,10');

writeln(final,'mov di,0');

writeln(final,'mov si,ax');

writeln(final,'cmp ax,0');

writeln(final,'jns @a');

writeln(final,'neg si');

writeln(final,'mov ah,2');

writeln(final,'mov dl, "-"');

writeln(final,'int 21h');

writeln(final,'mov ax,si');

writeln(final,’@a:');

writeln(final,'mov dx,0');

writeln(final,'div bx');

writeln(final,'add dl, 30h');

writeln(final,'mov vivod [di],dl');

writeln(final,'inc di');

writeln(final,'cmp al,0');

writeln(final,'jnz @a');

writeln(final,'mov cx,di');

writeln(final,'dec di');

writeln(final,'mov ah,2');

writeln(final,'@b:');

writeln(final,'mov dl,vivod[di]');

writeln(final,'dec di');

writeln(final,'int 21h');

writeln(final,'loop @b');

writeln(final,'mov dl, " "');

writeln(final,'int 21h');

writeln(final,'ret');

writeln(final,'end start');

if (buf[ub]='(') then count:=count+1 else if (buf[ub]=')') then count:=count-1;

if (count<>0) then err(0);

writeln(' Строка правильная');

close(f);

assign(f,'D:\tab_i.txt');

append(f);

for i:=1 to z-1 do

writeln(f,tab_i[i]);

close(f);

end;

Содержание исходного файла: 19+(32/8)-(45*3)#

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

.model tiny

.code

.386

org 100h

start:

mov ax,19

push ax

mov ax,32

push ax

mov ax,8

push ax

pop bx

pop ax

div bx

push ax

pop bx

pop ax

add ax,bx

push ax

mov ax,45

push ax

mov ax,3

push ax

pop bx

pop ax

mul bx

push ax

pop bx

pop ax

sub ax,bx

push ax

pop ax

mov bx,10

mov di,0

mov si,ax

cmp ax,0

jns @met7

neg si

mov ah,2

mov dl, "-"

int 21h

mov ax,si

@met7:

mov dx,0

div bx

add dl, 30h

mov vivod [di],dl

inc di

cmp al,0

jnz @met7

mov cx,di

dec di

mov ah,2

@met8:

mov dl,vivod[di]

dec di

int 21h

loop @met8

mov dl, " "

int 21h

ret

end start

Скомпонуем и скомпилируем получившуюся программу на ассемблере. В результате запуска созданного нами .com-приложения получим сообщение:

158

Данный результат является верным, следовательно обе программы составлены и работают правильно.

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