Здравствуйте, хабражители. Думаю, многие из вас слышали о программируемых калькуляторах (а некоторые даже использовали их). Как ни странно, здесь я не нашел ни одной статьи, рассказывающей о такой интересной вещи, и поэтому решил восполнить этот пробел и рассказать об основах программирования на калькуляторах.Некоторое время назад я нашел у себя в кладовке старый «Электроника МК-61», принадлежавший моему папе. Естественно, я не мог упустить такой шанс освоить не совсем «стандартное» программирование на калькуляторе. (В случае, если у вас нет программируемого калькулятора, вы можете скачать эмулятор здесь)
Память
Прежде всего необходимо понять, как устроена память в этом калькуляторе. В распоряжении пользователя имеется 4 стековых регистра: X, Y, Z, T. Содержимое регистра X всегда показывается на экране (в режиме расчетов), ввод чисел тоже идет в него. По сути, стековая память после включения калькулятора выглядит так:
T 0
Z 0
Y 0
X 0
Для помещения чего-либо в стек используется клавиша
[В↑]. Она копирует содержимое регистра X в регистр Y, значение регистра Y в Z, Z в T, а значение, находившееся в T теряется. То есть, если перед нажатием на кнопку [В↑] в регистрах были значенияT 5
Z 8
Y 14,5
X 6,то после значения станут
T 8
Z 14,5
Y 6
X 6Кроме того существует команда, позволяющая циклически сдвинуть все значения регистров: T в Z, Z в Y, Y в X, X в T. Для этого нужно нажать
[F] [.]. Команда
[] меняет содержимое регистров X и Y местами.Команда
[CX] стирает содержимое регистра X.Помимо стековой памяти, в калькуляторе есть 15 адресуемых регистров (RG0-RGE). Для работы с ними используются клавиши
[X→П] и [П→X]. Первая команда помещает содержимое регистра X в соответствующий адресуемый регистр. Например, последовательность команд [4] [X→П] [0] помещает в регистр RG0 число 4. Вторая команда, как вы уже догадались, копирует содержимое адресуемого регистра в регистр X. То есть [П→X] [0] поместит в X число 4.Важно помнить, что после выключения калькулятора значения всех регистров стираются.
Расчеты
Главное, что необходимо знать перед началом расчетов — в МК-61 используется обратная польская нотация (ОПН). Если нам нужно совершить какую-либо унарную операцию, она совершается над числом, находящимся в регистре X. При этом значения других регистров не меняются. Бинарные операции осуществляются над содержимыми регистров Y и X (именно в таком порядке). Значение результата помещается в X, Z помещается в Y, T копируется в Z. Предыдущее значение регистра X помещается в служебный регистр X1. Таким образом, если нам нужно посчитать банальное 2 + 3 (в ОПН 2 3 +), то нужно нажать на калькуляторе клавиши:
[2] [В↑] [3] [+]. При этом значения регистров меняются следующим образом:До всех операций:
T 8
Z 14,5
Y 6
X 0После нажатия клавиш
[2] [В↑] [3]:T 14,5
Z 6
Y 2
X 3После нажатия
[+]:T 14,5
Z 14,5
Y 6
X 5Попробуем провести чуть более сложные вычисления, например, (15 + 2 / 5) * 7 + 10. В ОПН это выражение можно записать так: 15 2 5 / + 7 * 10 +. Для того, чтобы это посчитать на калькуляторе, мы должны нажать клавиши:
[15] [В↑] [2] [В↑] [5] [/] [+] [7] [*] [10] [+].Программирование
Так, ну а это уже интереснее :). Для перехода в режим программирования нужно нажать
[F] [ВП]. На дисплее появятся 00. Это означает номер текущей команды. Вообще, программа в МК-61 представляет собой последовательность команд, необходимых для решения задачи. Обычно это арифметические операции, цифры, иногда специальные коды циклов и ветвлений. Всего программа может состоять не более чем из 105 команд, которые нумеруются от 00 до 99. Для ввода команды необходимо нажать соответствующую ей клавишу. Вот таблица соответствия кодов и клавиш калькулятора:
В режиме программирования видно 3 последних введенных операции. Например
02 01 0E 06 на дисплее означает:06— адрес следующей вводимой команды0E, 01, 02— три последовательные команды, расположенные соответственно по адресам 03, 04, 05.
Основы
Разберем простейшую задачу нахождения площади круга по формуле πr2. Для того, чтобы калькулятор решил эту задачу, введем следующие команды в режиме программирования (
[F] [ВП]) (будем считать что радиус окружности находится в регистре RG1): // Первые две цифры — адрес команды, потом нажимаемые клавиши
00 [П→X] [1] // Вызываем значение регистра RG1 в регистр X (61)
01 [F] [*] // Возводим в квадрат радиус (22)
02 [F] [+] // Вызываем в X пи (20)
03 [*] // Перемножаем содержимое X и Y (12)
04 [С/П] // Специальная команда для останова (без нее программа не остановится) (50)Вот и все. Теперь мы должны перейти в режим вычислений с помощью команды
[F] [/-/], а затем нужно нажать клавишу [В/О] для перехода к началу программы. Занес��м число 5 в регистр RG1 ([5] [X→П] [1]) и нажмем [С/П] для начала выполнения. После того, как калькулятор пройдет все шаги, на экране должно появиться число 78,539815 — площадь круга с радиусом 5.Безусловный и условный переходы
С помощью команды
[БП] (51) можно осуществить безусловный перезод (goto) по нужному адресу. Для этого в режиме программирования нужно нажать [БП] а затем две цифры адреса, по которому мы хотим перейти. Когда калькулятор при выполнении программы дойдет до этого оператора, он продолжит выполнение уже с команды по указанному адресу. Например:...
10 [F] [-] // 21
11 [БП] // 51
12 [4] [2] // Адрес перехода (42)
...
42 [+] // 10В данном случае после шага 12 калькулятор перейдет сразу к шагу 42.
Условный переход гораздо полезнее. Для осуществления условного перехода существует 4 команды:
[X >= 0], [X < 0], [X = 0] и [X != 0]. С помощью этих команд проверяют содержимое регистра X на выполнения условия. В случае, если условие не выполняется, управление переходит к адресу, указанному после оператора, иначе (если условие выполняется) адрес игнорируется и программа продолжает нормально выполняться далее. Например:...
09 [F] [*] // 22
10 [F] [ШГ←] // "if (X == 0)" (5E)
11 [4] [2] // В случае, если условие ложно, переходим по адресу 42 (42)
12 [+] // В случае, если X = 0 (10)
...
42 [4] // 04Циклы
Циклы можно реализовать с помощью команд условного перехода, но, кроме того, для организации циклов в МК-61 используются команды L0-L3 (
[F] [П→X], [F] [X→П], [F] [БП] и [F] [ПП]). Эти команды оперируют с содержимым регистров RG0-RG3 соответственно. При каждом выполнении команды цикла из содержимого соответствующего регистра вычитается 1 и производится сравнение с нулём. Если содержимое регистра не равно нулю, происходит переход по адресу, записанному после команды цикла, если равно, то происходит переход к команде, следующей за адресом перехода цикла. Чтобы было понятнее, посмотрим на примере. Будем считать факториал числа, находящегося в регистре X.// В RG0 будем хранить счетчик цикла, в RG1 произведение.
00 [X→П] [0] // Заносим значение X в RG0 - инициализируем счетчик цикла (40)
01 [1] // Заносим 1 в X (01)
02 [X→П] [1] // Инициализируем единицей значение RG1 - произведение (41)
03 [П→X] [1] // Заносим в стек текущее значение произведения (61)
04 [П→X] [0] // Заносим в стек текущее значение счетчика цикла (60)
05 [*] // Перемножаем их (12)
06 [X→П] [1] // Заносим результат в произведение (41)
07 [F] [П→X] // L0 - уменьшаем счетчик на единицу и проверяем на равенство нулю. Если не равен... (5Г)
08 [0] [3] // ...переходим к команде по адресу 03... (03)
09 [С/П] // ...иначе - останов (50)Заключение
Конечно, эта статья — далеко не полное руководство по программированию на МК-61. Интересующимся в более глубоком освоении этой темы рекомендую почитать инструкцию (pdf, 6 MB) к этому замечательному калькулятору.
