Начнем с простого сложения. Допустим, вы хотите, чтобы регистровая машина прибавила содержимое одного регистра (скажем, регистра 1) к содержимому другого регистра (регистра 2). Таким образом, если в регистре 1 содержится [3], а в регистре 2 содержится [4], мы хотим, чтобы в итоге программа сделала так, чтобы содержимое регистра 2 стало равняться [7], потому что 3 + 4 = 7. Вот программа, которая справится с этой задачей, написанная на простом языке РПА (регистровое программирование на ассемблере):
Первые две инструкции образуют простой цикл, в рамках которого регистр 1 декрементируется, а регистр 2 инкрементируется снова и снова, пока регистр 1 не опустеет. Это “заметит” блок обработки данных, который в результате сделает переход на шаг 3, останавливающий программу. Блок обработки данных не может сказать, каково содержимое регистра, если только это содержимое не 0. Если снова представить ящики с бобами, можно сказать, что блок обработки данных слеп и не видит, что находится в регистре, пока он не опустеет, потому что отсутствие содержимого он может определить на ощупь. Несмотря на то что, в принципе, он не может сказать, каково содержимое регистров, если задать ему программу 1, он всегда будет прибавлять содержимое регистра 1 (какое бы число ни содержалось в регистре 1) к содержимому регистра 2 (какое бы число ни содержалось в регистре 2), а затем останавливаться. (Вы понимаете, почему так должно происходить всегда? Разберите несколько примеров, чтобы удостовериться.) Вот любопытный способ на это взглянуть: регистровая машина мастерски умеет складывать числа, не зная, какие именно числа она складывает (а также что такое числа и что такое сложение)!
а. Сколько шагов потребуется регистровой машине, чтобы сложить 2 + 5 и получить 7, выполняя программу 1 (считая Кон отдельным шагом)?
б. Сколько шагов потребуется машине, чтобы сложить 5 + 2?
(Какой из этого можно сделать вывод?)[29]
Этот процесс можно изобразить наглядно, построив так называемый граф потока. Каждый кружок обозначает инструкцию. Число в кружке обозначает адрес регистра, с которым необходимо произвести манипуляции (а не содержимое регистра), “+” обозначает инструкцию Инк, а “–” – инструкцию Деп. Программа всегда начинается с α, альфы, и завершается, когда достигает Ω, омеги. Стрелки показывают переход к следующей инструкции. Обратите внимание, что каждая инструкция Деп имеет две исходящих стрелки, одну для направления, в котором двигаться, если декрементировать содержимое регистра возможно, а другую – если невозможно, потому что содержимое регистра 0 (переход на ноль).
Теперь давайте напишем программу, которая просто перемещает содержимое одного