Выполнение контрольного примера
Содержание контрольного примера
Разберём программу следующего содержания: пользователь вводит 2 целых числа, после чего выводится результат вычисления выражения в зависимости от введенных чисел.
Полный текст программы приведён ниже. Данная программа корректна (диагностика ошибок лежит вне задач выполнения контрольного примера).
var
a: integer;
b: integer;
c: real;
d: real;
begin
Write('Enter a (integer): ');
read(a);
Write('Enter b (integer): ');
read(b);
writeln;
c := (a + 5)*6/(5+5) + b;
write('c := (a + 5)*6/(5+5) + b;');
writeln;
write('c = ');
write(c);
end.
Выполнение лексического анализа
Данная программа иллюстрирует работу с целыми числами: ввод с терминала и вывод на терминал. Ниже приведена таблица лексем данной программы, сформированная менеджером таблиц компилятора:
--- Integer table ---
0 5
1 6
2 5
3 5
--- String table ---
0 "Enter a (integer): "
1 "Enter b (integer): "
2 "c := (a + 5)*6/(5+5) + b;"
3 "c = "
--- Identifiers ---
0 a
1 b
2 c
3 d
Выполнение синтаксического анализа
Синтаксический анализатор допускает данную программу и выполняет перевод текста программы во внутреннее представление. Поток тетрад, сформированный синтаксическим анализатором, представлен ниже:
Таблица имен
------------------------------------------
v0 Integer 0
v1 Integer 1
v10 String Литерал 2
v11 String Литерал 3
v2 Real 2
v3 Real 3
v4 String Литерал 0
v5 String Литерал 1
v6 Integer Литерал 0
v7 Integer Литерал 1
v8 Integer Литерал 2
v9 Integer Литерал 3
vInt0 Integer 0 Временная
vInt1 Integer 0 Временная
vReal0 Real 0 Временная
vReal1 Real 0 Временная
vReal2 Real 0 Временная
Промежуточный код
------------------------------------------
Write str v4
Read int v0
Write str v5
Read int v1
WriteLn
Plus v0 v6 vInt0
Mult vInt0 v7 vInt1
Plus v8 v9 vInt0
ITOF vInt1 vReal0
ITOF vInt0 vReal1
Div FP vReal0 vReal1 vReal2
ITOF v1 vReal0
Plus FP vReal2 vReal0 vReal1
Assign FP vReal1 v2
Write str v10
WriteLn
Write str v11
Write real v2
Выполнение генерации кода
На заключительном этапе промежуточный код обрабатывается генератором кода. В результате формируется выходной файл следующего содержания:
.286
DOSSEG
.MODEL SMALL
EXTRN _write_char: PROC
EXTRN _write_int : PROC
EXTRN _write_flt : PROC
EXTRN _write_str : PROC
EXTRN _write_ln : PROC
EXTRN _read_char : PROC
EXTRN _read_int : PROC
EXTRN _read_flt : PROC
EXTRN _read_str : PROC
EXTRN _copy_str : PROC
EXTRN _concat_str: PROC
; **************************************
; *********** Сегмент данных ***********
.DATA
v0 DW 0h ; a
v1 DW 0h ; b
v10 DB "c := (a + 5)*6/(5+5) + b;",0
v11 DB "c = ",0
v2 DD 0h ; c
v3 DD 0h ; d
v4 DB "Enter a (integer): ",0
v5 DB "Enter b (integer): ",0
v6 DW 5
v7 DW 6
v8 DW 5
v9 DW 5
vInt0 DW 0h ; временная
vInt1 DW 0h ; временная
vReal0 DD 0h ; временная
vReal1 DD 0h ; временная
vReal2 DD 0h ; временная
; **************************************
; ************* Сегмент кода ***********
.CODE
PUBLIC _asmentry
_asmentry PROC
; Собственно код...
; Write str v4
push offset v4
call _write_str
add sp, 2
; Read int v0
push offset v0
call _read_int
add sp, 2
; Write str v5
push offset v5
call _write_str
add sp, 2
; Read int v1
push offset v1
call _read_int
add sp, 2
; WriteLn
call _write_ln
; Plus v0 v6 vInt0
mov AX, word ptr v0
add AX, word ptr v6
mov word ptr vInt0, AX
; Mult vInt0 v7 vInt1
mov AX, word ptr vInt0
imul word ptr v7
mov word ptr vInt1, AX
; Plus v8 v9 vInt0
mov AX, word ptr v8
add AX, word ptr v9
mov word ptr vInt0, AX
; ITOF vInt1 vReal0
fild word ptr vInt1
fstp dword ptr vReal0
fwait
; ITOF vInt0 vReal1
fild word ptr vInt0
fstp dword ptr vReal1
fwait
; Div FP vReal0 vReal1 vReal2
fld dword ptr vReal0
fld dword ptr vReal1
fdiv
fstp dword ptr vReal2
fwait
; ITOF v1 vReal0
fild word ptr v1
fstp dword ptr vReal0
fwait
; Plus FP vReal2 vReal0 vReal1
fld dword ptr vReal2
fld dword ptr vReal0
fadd
fstp dword ptr vReal1
fwait
; Assign FP vReal1 v2
fld dword ptr vReal1
fstp dword ptr v2
fwait
; Write str v10
push offset v10
call _write_str
add sp, 2
; WriteLn
call _write_ln
; Write str v11
push offset v11
call _write_str
add sp, 2
; Write real v2
push dword ptr v2
call _write_flt
add sp, 4
RET
_asmentry ENDP
END
Выполнение программы
Как указывалось выше, для получения исполнимого кода необходимо вызвать ассемблер TASM на полученный код программы, после чего скомпоновать объектный модуль программы с объектным модулем библиотеки. Итогом работы является исполняемый файл программы (в нашем случае – “Arithm2.exe”).
Выполним программу несколько раз, чтобы убедиться в её работоспособности и корректности. Протокол нескольких ее запусков приведён ниже:
Достаточно легко убедиться, что программа выполняется корректно. В результате корректной организации взаимодействия с библиотекой поддержки, правильно работают функции ввода с терминала и вывода на терминал.