
LoSWS_L_2_4_ВиртМашина
Лекция 2.4 Виртуальная машина
Прежде чем разрабатывать блок формирования целевого кода, необходимо знать грамматику этого кода. Первоначально рассмотрим структуру команд стековой машины и разработаем для нее транслятор. Затем разработаем транслятор для виртуальной 3-х адресной машины. Этот код удобен для оптимизации.
Стековая машина имеет нуль-адресную систему команд и прекрасно приспособлена для обработки выражений представленных в обратной польской записи. Но команды пересылки, переходов требуют 1 адреса. Поэтому приходится использовать либо 1 адресную систему команд (в арифметических операциях адрес не будет использоваться), либо нуль-адресную систему команд (адреса располагаются сразу за командой).
В учебных целях для простоты разработаем одноадресную виртуальную машину:
КОП |
Адрес |
Архитектура виртуальной машины
Нуль-адресные операции: арифметические, отношения, логические
КОП |
Адрес = 0 |
Pop – функция извлечения числа из вершины стека
Push(значение) – процедура записи значения в стек
№ |
|
Мат. знак |
Мнемо-код |
|
1 |
унарный минус |
- |
op_um |
|
2 |
модуль |
abs |
op_abs |
|
3 |
сложение |
+ |
op_add |
push(pop+pop) |
4 |
вычитание |
– |
op_sub |
buf=pop push(pop-buf) |
5 |
умножение |
* |
op_mult |
push(pop*pop) |
6 |
деление целочислен |
/ |
op_div |
. . . . |
7 |
остаток |
% |
op_mod |
. . . . |
8 |
меньше |
< |
op_less |
buf=pop if (pop<buf) then push(1) else push(0) |
9 |
больше |
> |
op_grt |
. . . . |
10 |
равно |
= |
op_equ |
. . . . |
11 |
или |
| |
op_or |
push(pop | pop) |
12 |
и |
& |
op_and |
. . . . |
13 |
не |
~ |
op_not |
|
14 |
Вывод из вершины стека в окно вывода |
|
op_view |
|
15 |
останов |
|
op_stop |
|
Дополнительные команды
№ |
|
Мат. знак |
Мнемо-код |
|
1 |
|
>= |
op_ |
|
2 |
|
<= |
op_ |
|
3 |
|
<> |
op_ |
|
4 |
|
!> |
op_ |
|
5 |
|
!< |
op_ |
|
6 |
|
!= |
op_ |
|
7 |
|
e2 |
op_ |
|
8 |
|
sign |
op_ |
|
Операции пересылки и перехода
КОП |
Адрес переменной |
КОП |
константа |
curr_code.op - поле операции текущей команды
curr_code.adr – адрес перехода или значение константы в текущей команде