Существуют подпрограммы, очень часто используемые одной и той же типовой программой или одним и тем же программистом в различных программах. Передача управления программой в подпрограмме выполняется одной командой вызова (CALL). Возврат или восстановление управления основной программой осуществляется командой возврата (RET). Кроме того, используются команды размещения в стек и извлечения из стека – используются как текущие вместе с подпрограммой.
Пример.
В задачу МП входит ввести 2 отобранных числа, образовать их сумму и сохранить ее, затем, эта сумма должна быть умножена на масштабирующий коэффициент и размещена так же в памяти. Это связано с тем, что предыдущая сумма должна быть восстановлена в аккумулятор, затем эта сумма проверяется знаком принятия решения и в этом случае, если она больше 10Н, программа переводится на сигнализацию.
Программа задумана для образования циклов неопределенно долго и принимать новые наборы данных в каждом цикле. Программа покидает цикл для процедуры аварийной сигнализации (АС) только в случае возникновения соответствующей ситуации.
|
|
Нарисуем подробную блок-схему.
Метка | Мнемоника | Операнд | Комментарий |
LXI | SP, 20CØ | Поместить число 20CØ в указатель стека. | |
LXI | Н, 2040 | Поместить адрес 2040 в пару регистров HL (указать область ОЗУ, в которой будут находиться данные). | |
XRA | A | Сброс аккумулятора в ØØ. | |
ADD | М | Сложить содержимое аккумулятора с М (2040). | |
INX | H | Инкрементировать пару регистров HL. | |
ADD | M | Сложить содержимое аккумулятора с содержимым ячейки памяти 2041. | |
PUSH | PSW | Поместить в стек содержимое аккумулятора и индикатора регистра состояния. | |
CALL | MULTIPLAY | Вызов подпрограммы MULTIPLAY, начинающейся с адреса 2042. | |
INX | H, 2042 | Инкремент HL до 2042. | |
MOV | M, A | Разместить произведение в ячейку памяти 2042. |
Три первые команды восстанавливают указатель стека пару регистров HL и аккумулятор соответственно до 20СØ, 2040 и ØØ.
Четвертая команда складывает содержимое аккумулятора с содержимым ячейки памяти, на которую указывает пара регистров HL. Например, содержимое памяти по адресу 2040 – Ø5.
После выполнения четвертой команды, содержимое аккумулятора будет Ø5 (ØØ + Ø5 = Ø5).
Пятая команда основной программы инкрементирует содержимое пары регистров HL.
Шестая команда складывает содержимое памяти по адресу 2041 (Ø9) с содержимым аккумулятора. В результате Ø5 + Ø9= ØЕ.
Следующая команда PUSH PSW сохраняет содержимое аккумулятора и индикаторы регистра состояния. Это должно быть выполнено потому, что следующая команда вызова подпрограммы разрушит содержимое этих регистров, при выполнении программы умножения.
|
|
Операция вызова помещает адрес команды в последовательность основной программы в стек и затем переходит к адресу первой команды подпрограммы умножения.
Например, адрес 2050 (adr. 2050). В примере подпрограммы осуществляется умножение суммы ØЕ * 2 = 1С и произведение помещается в аккумулятор. После возврата в основную программу адрес следующей последовательной команды извлекается из стека и например, равен 200Е.
Т.к. команды размещения в стек и извлечение из него парные, то содержимое аккумулятора и регистра состояния восстанавливается командой POP PSW.
Теперь содержимое аккумулятора является не произведением, а сумма ØЕ. Эта сумма будет тестируема следующей командой CPI. Две следующие команды основной программы для тестирования суммы в аккумулятор. Команда сравнить непосредственно (CPI) выполняет операцию вычитание (ØЕ – 10 = FE). Результат вычитания будет FE, который представлен в дополнительном коде. Т.е. содержимое аккумулятора меньше, чем 10. Индикатор CY равен 1 и МП переходит к символическому адресу START.
Для операции двоичного умножения могут быть использованы различные способы на базе команд МП, однако, вытекающие непосредственно из правил умножения методы приводят нас к повторяющемуся сложению.
Например:
При повторяющемся сложении это операция выглядит иначе:
В этом случае множимое повторяется слагаемым число раз, равное множителю, а результат этой операции будет произведение. В нашем примере вместо ØЕ * Ø2 = ТС будет ØЕ + = 1.
Первый шаг обеспечивает хранение текущего содержимого пары регистров HL в стеке. Три следующих шага восстанавливают регистры (L), (H) и (A). Регистр (L) будет содержать множитель (Ø2) и он будет инкрементирован программой до. Регистр (Н) содержит множимое (ØЕ), т.е. сумму, посланную в подпрограмму основной программы. Аккумулятор = ØØ. Пятый шаг соответствует сложению множимого (ØЕ) с аккумулятором (ØØ). Частное произведение ØЕ затем сохраняется в ОЗУ по адресу, например, 2020. В то время, как аккумулятор используется для декрементирования содержимого регистра (L). На шаге принятия решения возникает вопрос (L) = ØØ? Если ответ отрицательный, программа переходит снова в цикл. Если ответ положительный, ветвится вправо. Содержимое пары регистров HL восстанавливается командой извлечения из стека и наконец команда возврата возвращает нас в основную программу.
Нарисуем блок-схему.
Метка | Мнемоника | Операнд | Комментарий |
PUSH | H | Поместить в стек содержимое регистра HL (20C1). | |
MVI | L, Ø2 | Поместить множитель Ø2 в регистр L. | |
MOV | H, A | ØE из (А) поместить в (Н). | |
XRA | A | Сброс (А) в ØØ. | |
LOOP | ADD | H | Сложить (А) с (Н). |
STA | Поместить частное произведение (ØØ + ØE = ØE) в (М). | ||
MOV | A, L | Содержимое (L) поместить в (А). | |
DCR | A | Декремент (А). | |
MOV | L, A | Содержимое (А) поместить в (L). | |
LDA | Поместить в Аккумулятор содержимое ячейки памяти 2020. | ||
IZ | DONE | Перейти к DONE, если индикатор Z=1, т.е. регистр L декрементируется в ØØ, если нет – продолжить последовательно. | |
IMP | LOOP | Перейти всегда к символическому адресу LOOP. | |
DONE | POP | H | Извлечь из стека содержимое пары регистров HL. |
RET | Возврат в основную программу. |