В.Г. Баула - Введение в архитектуру ЭВМ и системы программирования (975817), страница 4
Текст из файла (страница 4)
В данном примере при записи программы на месте кода операции мы будем для удобства вместо числа указывать его мнемоническое обозначение. Разумеется, потом, перед вводом программы необходимо будет заменить эти мнемонические обозначения соответствующими им числами.
Для определения того, является ли значение переменной x больше, меньше или равным константе 2, мы будем выполнять операцию вычитания x–2, получая в регистре w значение 0 при x=2, 1 при x<2 и 2 при x>2. При этом сам результат операции вычитания нам не нужен, но по нашему формату команд указание адреса ячейки для записи результата является обязательным. Для записи таких ненужных значений мы будем чаще всего использовать ячейку с номером 0. В соответствии с принципом однородности памяти, эта ячейка ничем не отличается от других, то есть, доступна как для записи, так и для чтения данных. В некоторых реальных ЭВМ этот принцип нарушается: при считывании из этой ячейки всегда возвращался нуль, а запись в ячейку с адресом ноль физически не осуществляется (на практике такой принцип работы c с этой ячейкой иногда удобнее).
Для хранения переменных x и y выделим ячейки 100 и 101 соответственно. Программист сам определяет порядок размещения в программе трёх ветвей нашего условного оператора присваивания. Мы будем сначала располагать вторую ветвь (x=2), затем первую (x<2), а потом третью (x>2). На рис. 3.2 приведён текст этой программы.
№ | Команда | Комментарий | |||
001 | ВВЦ | 100 | 001 | 000 | Read(x) |
2 | СЛЦ | 101 | 100 | 011 | y := x+2 |
3 | ВЧЦ | 000 | 100 | 011 | <000> := x–2; формирование w |
4 | УСЛ | 005 | 007 | 009 | Case w of 0: goto 005; 1: goto 007; 2: goto 009 end |
5 | ВЫЦ | 011 | 001 | 000 | Write(2) |
6 | СТОП | 000 | 000 | 000 | Конец работы |
7 | ВЫЦ | 101 | 001 | 000 | Write(y) |
8 | СТОП | 000 | 000 | 000 | Конец работы |
9 | УМЦ | 101 | 011 | 101 | y := 2 * y |
010 | БЕЗ | 000 | 007 | 000 | Goto 007 |
1 | 00 | 000 | 000 | 002 | Целая константа 2 |
Рис 3.2. Текст программы второго примера.
Обратите внимание, что константа 2 неотличима от команды пересылки содержимого второй ячейки памяти в нулевую ячейку, именно такая команда и будет выполняться, если эта константа будет выбрана на регистр команд устройства управления.
3.2.3. Пример 3. Реализация цикла.
В качестве следующего примера напишем программу для вычисления начального отрезка гармонического ряда:
Для хранения переменных n,y и i выделим ячейки 100, 101 и 102 соответственно. В этом алгоритме мы реализуем цикл с предусловием, поэтому при вводе n<1 тело цикла не будет выполняться ни одного раза, и наша программа будет выдавать нулевой результат. На рис. 3.3 приведена возможная программа для решения этой задачи.
Сделаем некоторые замечания к этой программе. В нашем языке у нас нет команды деления целого числа на вещественное, поэтому при вычислении величины 1.0/i нам пришлось отдельной командой
ВЕЩ 000 000 102
преобразовать значение целой переменной i в вещественной значение. Обратите также внимание, что для нашей учебной машины мы ещё не определили формат представления вещественных чисел, поэтому в ячейке с адресом 14 стоит пока просто условное обозначение константы 1.0, а не её машинное представление.
№ | Команда | Комментарий | |||
001 | ВВЦ | 100 | 001 | 000 | Read(n) |
2 | ВЧВ | 101 | 101 | 101 | y := 0.0 |
3 | ПЕР | 102 | 000 | 013 | i := 1 |
4 | ВЧЦ | 000 | 102 | 100 | i := i–n; формирование w |
5 | УСЛ | 006 | 006 | 011 | If i>n then goto 011 |
6 | ВЕЩ | 000 | 000 | 102 | <000> := Real(i) |
7 | ДЕВ | 000 | 014 | 000 | <000> := 1.0/<000> |
8 | СЛВ | 101 | 101 | 000 | y := y+<000> |
9 | СЛЦ | 102 | 102 | 013 | i := i+1 |
010 | БЕЗ | 000 | 004 | 000 | Следующая итерация цикла |
1 | ВЫВ | 101 | 001 | 000 | Write(y) |
2 | СТОП | 000 | 000 | 000 | Стоп |
3 | 00 | 000 | 000 | 001 | Целая константа 1 |
4 | <1.0> | Вещественная константа 1.0 |
Рис 3.3. Текст программы третьего примера.
3.2.4. Пример 4. Работа с массивами.
Пусть требуется написать программу для ввода массива x из 100 вещественных чисел и вычисления суммы всех элементов этого массива:
Будем предполагать, что длина программы не превышает 200 ячеек, и поместим массив x, начиная с 200-ой ячейки памяти. Вещественную переменную S с начальным значением 0.0 и целую переменную i с начальным значением 100 разместим в конце текста программы. На рис. 3.4 приведён текст этой программы.
№ | Команда | Комментарий | |||
001 | ВВВ | 200 | 100 | 000 | Read(x); массив x в ячейках 200299 |
2 | СЛВ | 008 | 200 | 008 | S := S+x[1] |
3 | СЛЦ | 002 | 002 | 011 | Модификация команды в ячейке 2 |
4 | ВЧЦ | 010 | 010 | 009 | n := n-1 |
5 | УСЛ | 006 | 006 | 002 | Следующая итерация цикла |
6 | ВЫВ | 008 | 001 | 000 | Write(S) |
7 | СТОП | 000 | 000 | 000 | Стоп |
8 | <0.0> | Переменная S = 0.0 | |||
9 | 00 | 000 | 000 | 001 | Целая константа 1 |
010 | 00 | 000 | 000 | 100 | Переменная n с начальным значением 100 |
1 | 00 | 000 | 001 | 000 | Константа переадресации |
Рис 3.4. Текст программы четвёртого примера.
Рассматриваемая программа выделяется своим новым приёмом программирования и может быть названа самомодифицирующейся программой. Обратим внимание на третью строку программы. Содержащаяся в ней команда изменяет исходный код программы (команду в ячейке 2) для организации цикла перебора элементов массива. Модифицируемая команда рассматривается как целое число, которое складывается со специально подобранное константой переадресации. Согласно одному из принципов фон Неймана, числа и команды в учебной машине неотличимы друг от друга, а, значит, изменяя числовое представление команды, мы можем изменять и её суть.
У такого метода программирования есть один существенный недостаток: модификация кода программы внутри её самой может привести к путанице и вызвать появление ошибок. Кроме того, самомодифицирующуюся программу трудно понимать и вносить в неё изменения. В нашей учебной машине это, однако, единственный способ обработки массивов. В других архитектурах ЭВМ, с которыми мы познакомимся несколько позже, есть и другие, более эффективные способы работы с массивами, поэтому метод с модификацией команд не используется.
3.3. Формальное описание учебной машины
При описании архитектуры учебной ЭВМ на естественном языке многие вопросы остались нераскрытыми. Что, например, будет после выполнения команды из ячейки с адресом 511? Какое значение после нажатия кнопки ПУСК имеют ячейки, расположенные вне введённой программы? Как представляются целые и вещественные числа? Для ответа на почти все такие вопросы мы приведём формальное описание нашей учебной машины. В качестве метаязыка мы будем использовать Турбо-Паскаль, на котором Вы работаете. Другими словами, мы напишем программу, выполнение которой моделирует работу нашей учебной машины, т.е. наша машина, по определению, работает почти так же, как и написанная нами программа на Паскале.