
- •«Системное программное обеспечение»
- •Лабораторная работа №1 Формирование очередей в динамической памяти
- •Лабораторная работа №2 Программирование конечного автомата
- •Лабораторная работа №3 Программирование конечного автомата для транслитерации
- •2) Исходный текст программы:
- •3) Результат:
- •Лабораторная работа №4 Программирование конечного автомата
- •2) Исходный текст программы:
- •Лабораторная работа №5 Программирование лексического анализатора
- •Лабораторная работа №6 Лексический анализатор. Процедура, которая не смещает указатель входного потока
- •Лабораторная работа №7 Рекурсивный спуск
- •2) Исходный текст программы:
- •Лабораторная работа №8 Синтаксический анализатор логического выражения.
- •2) Исходный текст программы:
- •Лабораторная работа №9 Синтаксический анализ для оператора присваивания
- •2) Исходный текст программы:
- •Лабораторная работа №10 Разработка калькулятора на основе рекурсивного спуска
- •Лабораторная работа №11 Генерация кода на ассемблере для арифметического выражения
Лабораторная работа №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
Данный результат является верным, следовательно обе программы составлены и работают правильно.