15.4 Компилятор усеченного языка программирования Си
Построение компилятора для реального, хотя и усеченного, языка программирования
является достаточно сложным делом. В литературе опубликован текст компилятора
RatC для усеченного языка программирования Си. Исходный код этого компилятора
имеется в файле . Дадим краткое описание этого компилятора. Этот компилятор
генерирует ассемблерный код для некоторого виртуального микропроцессора,
похожего на микропроцессор Intel 8080. В нем имеется четыре регистра: PC-
счетчик команд, SP- указатель стека, P- первый регистр данных, S- второй
регистр данных.
| Таблица 15.3: Система команд |
| ldir.b |
<метка> |
загрузка данных, записанных в байте по адресу <метка> в регистр P |
| ldir.w |
<метка> |
загрузка данных, записанных в слове (16 разрядов по адресу <метка> в
регистр P |
| addr |
<значение> |
P=SP+значение |
| sdir.b |
<метка> |
сохранение байта их регистра P в байт по адресу <метка> |
| sdir.w |
<метка> |
сохранение слова их регистра P в слово по адресу <метка> |
| sind.b |
|
(S)=P.b пересылка байта из P по адреcу, заданному в S |
| sdir.w |
|
(S)=P (пересылка слова из P по адреcу, заданному в S) |
| lind.b |
|
считывание байта в регистр P, по адресу, записанному в P |
| lind.w |
|
считывание слова в регистр P, по адресу, записанному в P |
| call |
<метка> |
вызов подпрограммы (адрес возврата заносится в стек) |
| scall |
|
вызов подпрограммы из вершины стека (адрес возврата заносится в стек) |
| ujump |
<метка> |
безусловный переход |
| fjump |
<метка> |
переход если P==0 |
| modstk |
<значение> |
SP=SP+значение |
| swap |
|
обмен содержимого P и S |
| limm |
<значение> |
P=значение |
| push |
|
содержимое P заслать в стек |
| pop |
|
вытащить из стека и записать в S |
| xchange |
|
обмен значениями P и вершины стека |
| return |
|
возврат из подпрограммы |
| scale |
<значение> |
умножить содержимое P на значение |
| add |
|
P=S+вершина стека |
| sub |
|
P=S-P |
| mult |
|
P=S*P |
| div |
|
P=S/P остаток от деления в S |
| mod |
|
S=S/P остаток в P |
| or |
|
P=P|S поразрядное или |
| xor |
|
P=P?S поразрядное исключающее или |
| and
|
|
P=P&S поразрядной И |
| asr |
|
арифметический сдвиг вправо S на число бит, записанных в P, результат в P |
| asl |
|
арифметический сдвиг влево S на число бит, записанных в P, результат в P |
| neg |
|
поразрядная инверсия P |
| inc |
|
P=P+1 |
| dec |
|
P=P-1 |
| testeq |
|
если S равно P, то P=1, иначе P=0 |
| testne |
|
если S неравно P, то P=1, иначе P=0 |
| testlt |
|
если S меньше P, то P=1, иначе P=0 |
| testle |
|
если S меньше или равно P, то P=1, иначе P=0 |
Перенос и использование компилятора RatC
Особенность этого транслятора - транслятор написан на том же усеченном Си, что
является входным для самого транслятора. Это означает, что транслятор можно
переносить с одной вычислительной среды в другую. Например, если имеется
транслятор RatC и его исходный текст для вычислительной системы A, необходимо
получить транслятор для вычислительной системы B, то можно это получить
следующим образом:
1) изменяем исходный текст RatC(A) для вычислительной системы B, получаем
исходный текст RatC(B);
2) компилируем исходный текст RatC(B) на компиляторе RatC(A), получаем
компилятор RatC(B), работающий на вычислительной системе A;
3) компилируем исходный текст RatC(B) на компиляторе RatC(В) для вычислительной
системы A, получаем компилятор RatC(B), работающий на вычислительной системе B;
Эта схема работает при условии, что системные библиотеки вычислительных систем A
и B совпадают. Использовать компилятора RatC можно по нескольким направлениям:
1. Написать виртуальную машину, моделирующую систему команд RatC
2. Переделать RatC для системы команд заданного процессора.
3. Переделать RatC для конкретного ассемблера.
|