|
Программирование >> Структурное программирование
направлении, начиная с ячейки 99 в порядке убывания номеров ячеек). Теперь для этого оператора может быть сгенерирован код ЯМП. Код операции 10 (код операции чтения в ЯМП) умножается на 100 и к нему добавляется адрес х, определяемый из таблицы символических имен). Сгенерированная инструкция сохраняется в массиве ЯМП в ячейке 00. Счетчик команд увеличивается на 1, поскольку была сгенерирована одна команда ЯМП.
Рис. 15.26. Таблица символических имен для программы, приведенной на рис. 15.25 Следующим разбивается на лексемы оператор 15 rem check у == х В таблице символических имен осуществляется поиск номера строки 15 (который не находится). Помер строки помещается в таблицу как тип L и ему присваивается следующая ячейка массива 01 (вспомним, что операторы rem не генерируют код, поэтому значение счетчика команд не увеличивается). Затем разбивается на лексемы оператор 20 if у == X goto 60 Номер строки 20 помещается в таблицу символических имен как тип L и ему присваивается очередная ячейка массива ЯМП 01. Команда if показывает, что должно вычисляться условие. Переменная у не найдена в таблице, поэтому она помещается в нее и ей задается тип V и ячейка ЯМП 98. Затем генерируются инструк- ции ЯМП для оценки указанного условия. Так как в ЯМП не существует прямого аналога оператора if/goto, он должен быть смоделирован расчетом выражения, содержащего х и у, и условной передачей управления в зависимости от полученного результата. Если у равен х, то результат вычитания х из у равен нулю; поэтому можно использовать команду ЯМП передача управления по нулю branchzero, которая с помощью анализа результата вычитания про-имитирует оператор if/goto. Первый шаг этой имитации требует загрузить у (из ячейки 98 ЯМП) в аккумулятор. Эту операцию выполняет инструкция 01 +2098. Затем из значения в аккумуляторе вычитается х. Эту операцию выполняет инструкция 02 +3199. Значение в аккумуляторе может оказаться нулевым, положительным или отрицательным. Так как выполняется операция ==, мы хотим осуществить передачу управления по нулевому значению. Сначала проводится поиск в таблице номера строки, в которую передается управление (в нашем случае 60), но этот номер не находится. Поэтому 60 помещается в ячейку 03 массива flags и генерируется инструкция 03 +4200 (мы не можем добавить к этой инструкции ячейку, которой передается управление, поскольку ячейка массива ЯМП, соответствующая номеру строки 60, еще не известна). Значение счетчика команд увеличивается и становится равным 04. Компилятор обрабатывает оператор 25 rem increment у Номер строки помещается в таблицу символических имен как тип L и ему присваивается ячейка ЯМП 04. Значение счетчика команд в данном случае не увеличивается. Когда разбивается на лексемы оператор 30 let у = у + 1 номер строки помещается в таблицу символических имен как тип L и ему присваивается ячейка ЯМП 04. Команда let показывает, что эта строка является оператором присваивания. Сначала все символы в строке помещаются в таблицу символических имен (в том случае, если их в таблице еще нет). Целое значение 1 добавляется в таблицу символических имен как тип С и ему присваивается ячейка ЯМП 97. Затем правая часть оператора присваивания преобразуется из инфиксной записи в постфиксную. Далее оценивается постфиксное выражение (у 1 +). Символ у уже имеется в таблице символических имен и соответствующая ему ячейка памяти помещается в стек. Символ 1 также уже имеется в таблице символических имен и соответствующая ему ячейка памяти также помещается в стек. Когда встречается операция +, компилятор постфиксного выражения сначала выталкивает из стека правый операнд этой операции, затем выталкивает из стека левый операнд, после чего генерируются инструкции ЯМП 04 +2098 (загрузить у) 05 +3097 {прибавить 1) Результат выражения сохраняется во временной ячейке (96) с помощью инструкции 06 +2196 [сохранить во временной ячейке) И адрес этой временной ячейки помещается в стек. Теперь, когда вычисление выражения закончено, необходимо сохранить результат в у (т.е. в переменной в левой части оператора присваивания). Для этого временная ячейка загружается в аккумулятор и затем значение в аккумуляторе сохраняется в у с помощью инструкций 07 +20 96 [загрузить временную ячейку) 08 +2198 [сохранить у) Читатель, конечно, сразу же заметит, что программа на ЯМП получается избыточной. Мы вскоре обсудим этот вопрос. Когда разбивается на лексемы оператор 35 rem add у to total номер строки 35 помещается в таблицу символических имен как тип L и ему присваивается ячейка 09. Оператор 40 let t = t + у подобен строке с номером 30. Переменная t помещается в таблицу символических имен как тип V и связывается с ячейкой ЯМП 95. Генерируются команды с той же логикой и форматом, что и для строки с номером 30: 09 -f2095, 10 +3098, 11 +2194 и 13 +2195. Заметим, что результат операции t + у передается на временное хранение в ячейку 94 перед тем, как присваивается переменной t (95). Снова читатель может заметить, что инструкции, расположенные в ячейках 11 и 12, избыточны. И снова обещаем вскорости обсудить этот вопрос. Оператор 4 5 rem loop у является комментарием, так что номер строки 45 помещается в таблицу как тип L и связывается с ячейкой ЯМП 14. Оператор 50 goto 20 передает управление строке с номером 20. Номер строки 50 помещается в таблицу символических имен как тип L и ему приписывается ячейка ЯМП 14. Эквивалентом оператора goto в ЯМП является команда безусловного перехода branch (40), которая передает управление заданной ячейке ЯМП. Компилятор проводит поиск номера строки 20 и обнаруживает, что он соответствует ячейке ЯМП 01. Код операции (40) умножается на 100 и складывается с адресом 01. В итоге генерируется инструкция 14 +4001. Обрабатывается оператор 55 rem output result
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |