Эмуляторы одноадресных процессоров

1. [Одноадресный интерпретатор.] Реализуйте эмулятор процессора с системой команд: PUSH <число> (затолкнуть в стек), ADD, SUB, MUL, DIV (сложить, вычесть, умножить, разделить 2 последних числа в стеке), SQRT (квадратный корень из числа на вершине стека), РОР (вытолкнуть из стека), DUP (продублировать число на вершине стека), IN (ввести число), OUT (вывести) и STOP. Вычисления ведите в интерактивном режиме: ввел строку с командой—разобрал—выполнил. Должны быть команды отладки (распечатать весь стек и т.п.). Для проверки вычислите корень какого-нибудь квадратного уравнения.

2. [Одноадресный код.] Задача 1, но имеется программа с кодами операций (соответствующим командам), хранящаяся в массиве. Подумайте, как быть с PUSH (у нее есть аргумент). Должно быть чтение программы из файла с определенной структурой (подписи и т.п.).

3. [Одноадресный отладчик.] Задача 2, но сделайте отладчик (просмотр стека, пошаговое выполнение).

4. [Одноадресный транслятор.] Напишите транслятор с ассемблера для процессора из задачи 2.

5. [С константами.] Задача 3, добавляются команды IN <текст> (ввести число с приглашением) и OUT <текст> (вывести с пояснением). Подумайте, как хранить строки в программе. Соответственно модифицируйте транслятор.

6. [С переходами.] Задача 5, добавляются команды JMP <адрес> (переход на команду с определенным адресом) и JB (переход, если число на вершине стека меньше нуля). Модифицируйте транслятор, введите понятие метки, задаваемой идентификатором. Используйте двухпроходную схему: 1 проход — коды операций, 2 проход — корректировка адресов переходов.

7. [С подпрограммами.] Задача 6, добавляются команды CALL <адрес> (вызов процедуры с определенным адресом) и RET (возврат). Реализуйте стек вызовов (отдельно от стека вычислений. Подумайте, чем выгодно и невыгодно смешение стеков вызовов и вычислений).

8. [С памятью.] Задача 7, но вводится память из N ячеек и команды PUSH <адрес> и POP <адрес> (операции с ячейками памяти). В трансляторе пока не делайте описания данных (пусть они пока задаются через PUSH и РОР).

9. [С данными в программе.] Задача 8, но в трансляторе сделайте возможность задания переменных с именами и начальными значениями.

10. [С полем r/m/i и косвенной адресацией.] Задача 8 или 9, но сделайте так, чтобы аргументы команд PUSH, POP, переходов и вызовов можно было задавать в 3 формах: immediate (аргумент указан в команде, как в задаче 1), memory (аргумент в памяти — задача 7) и register (аргумент на вершине стека). Введите байт формата аргумента и байт длины команды (более правильно упаковать это в 1 байт). Учтите, что режимы могут комбинироваться!

11. [С графикой.] Задача 9 или 10 + добавьте графические команды.

12. [PostScript.] Реализуйте подмножество языка описания графических изображений Adobe PostScript. (Только не надо пытаться что-либо понять, смотря в PS-файлы! Они обычно генерятся графическими редакторами, там черт ногу сломит. Возьмите лучше файл с книжкой по PostScript, она простая.)