Алгоритм подпрограммы MAX (нахождение максимального элемента и вычисление множителя):
Алгоритм подпрограммы MULT (умножения и записи результата (Y) в ОЗУ):
<!-- Операция умножения реализована посредством многократного суммирования (кол-во циклов суммирования = множитель-1). Поскольку множимое состоит из двух байт (находится в паре DE), то суммирование производится сначала для младших байтов (счётчик переполнения – в регистре H), а потом для старших байтов (счётчик переполнения – в регистре L). Таким образом, первый (младший) байт Yнаходится в регистре D, второй байт – состоит из суммы старшего байта множимого (E) и счётчика переполнения младшего байта множимого (H), третий (старший) байт – в регистре L -->
Листинг программы приведён ниже:
CALL ADT ;вызов подпрограммы ADT (суммирование и нахождение
минимального элемента)
MVI B, 06 ;задание кол-ва сдвигов (B:=06H – 6 сдвигов равносильно
делению на 64)
CALL DIV ;вызов подпрограммы DIV (нахождение среднего значения)
CALLREZ1 ;вызов подпрограммы REZ1 (вычисление (4ACP – AMIN/4))
CALLMAX ;вызов подпрограммы MAX (вычисление AMAX/2)
CALLMULT ;вызов подпрограммы MULT (умножение)
RST 1 ;выход из программы
ADT: LXI H, 8100 ;задание адреса первого элемента (HL:=8100H)
MVI B, 40 ;задание кол-ва элементов (B:=64D=40H)
XRA A ;обнуление аккумулятора
LXI D, 0000 ;обнуление регистров E и D (пары DE) – старшего и младшего
байтов результата суммирования соответственно
MOVC, M ;будем считать первый элемент минимальным (С:=M(HL))
X1: MOVA, M ;переслать в аккумулятор текущий элемент (A:=M(HL))
CMPC ;сравниваем содержимое аккумулятора с текущим наименьшим
значением (A-C)
JPX2 ;при TS=0 (A-C≥0 → A≥C) переход на Х2
MOVC, A ;если же TS=1 (A-C<0 → A<C), сделать текущий элемент
наименьшим
X2: ADDD ;суммирование (A:=D+A)
MOV D, A ;пересылкаA→D
JNC X3 ;перейти на Х3 если нет переполнения
INR E ;произошло переполнение → прибавить 1 к старшему байту
результата суммирования
X3: INX H ;присвоить HL адрес следующей ячейки (HL:=HL+1)
DCR B ;уменьшение счётчика кол-ва элементов на 1 (B:=B-1)
JNZ X1 ;если элемент не последний - продолжить суммирование
RET ;выход из подпрограммы ADT
DIV:MOVA, E ;пересылаем старший байт в аккумулятор (E→A)
RAR ;циклический сдвиг вправо через ТС
MOVE, A ;возврат в Е старшего байта
MOVA, D ;пересылаем младший байт в аккумулятор (D→A)
RAR ;циклический сдвиг вправо через ТС
MOVD, A ;возврат в D младшего байта
ORAA ;обнуление флага переполнения (ТС:=0)
DCR B ;уменьшение счётчика кол-ва сдвигов на 1 (B:=B-1)
JNZ DIV ;если сдвиг не последний – продолжить
RET ;выход из подпрограммы DIV
REZ1: MOV Н, D ;пересылаем ACP в регистр Н
MVIE, 00 ;обнуление регистра Е
MOVD, C ;пересылка АMIN в регистр D
MVI B, 02 ;задание кол-ва сдвигов (B:=02H – 2 сдвигa равносильно
делению на 4)
CALL DIV ;вызов подпрограммы DIV (деление на 4)
MOVC, D;обратная пересылка в регистр С значения АMIN/4
MOVA, H ;отправляем ACP в аккумулятор
MVIE, 00 ;обнуление регистра E
MVIB, 03 ;записываем в регистр В количество циклов суммирования
(03 = 4 - 1)
X4: ADDH ;к аккумулятору прибавляем по одному значению ACP
JNCX5 ;если нет переполнения – перейти на Х5
INRE ;если произошло переполнение – увеличить старший байт на 1
X5: DCRB ;уменьшить кол-во циклов суммирования на 1
JNZX4 ;если цикл не последний – повторить суммирование
SUBC ;вычитание: 4АСР – AMIN/4
JPX6 ;если результат вычитания положителен – перейти на Х6
DCRE ;если результат вычитания отрицателен – вычесть 1 из
старшего байта
X6: MOVD, A ;переслать младший байт результата (4АСР – AMIN/4) в регистр
D (весь результат находится в паре DE)
RET ;выход из подпрограммы REZ1
MAX: LXI H, 8100 ;задание адреса первого элемента (HL:=8100H)
MVI B, 40 ;задание кол-ва элементов (B:=64D=40H)
MOVA, M ;будем считать первый элемент максимальным (A:=M(HL))
X7: CMPM ;сравниваем максимальный элемент с текущим (A-M(HL))
JPX8 ;при TS=0 (A-M(HL)≥0 → A≥M(HL)) переход на Х8
MOVA, M ;если же TS=1 (A-M(HL)<0 → A<M(HL)), сделать текущий
элемент максимальным
X8: INX H ;присвоить HL адрес следующей ячейки (HL:=HL+1)
DCR B ;уменьшение счётчика кол-ва элементов на 1 (B:=B-1)
JNZ X7 ;если элемент не последний - продолжить суммирование
RAR ;деление AMAX на 2
ORAA ;обнуление флага переполнения (ТС:=0)
MOVC, A;пересылка значения AMAX/2 в регистр C
RET ;выход из подпрограммы MAX
MULT: LXIH, 0000 ;обнуление регистров H и L
MOVB, C ;загрузить множитель (AMAX/2) в регистр В
DCRB ;уменьшение на 1 множителя
MOVA, D ;пересылка младшего байта множимого в аккумулятор
X9: ADDD ;суммируем по одному значению
JNCX10 ;если нет переполнения – перейти на Х10
INRH ;если было переполнение – увеличить счётчик переполнения
младшего байта на 1
X10: DCRB ;уменьшить кол-во циклов суммирования на 1
JNZX9 ;если цикл не последний – повторить суммирование
STA 80FD ;отправить первый (самый младший) байт результата (Y) в
ячейку ОЗУ 80FDH
MOVB, C ;загрузить множитель (AMAX/2) в регистр В
DCRB ;уменьшение на 1 множителя
MOVA, E;пересылка старшего байта множимого в аккумулятор
X11: ADDE ;суммируем по одному значению
JNCX12 ;если нет переполнения – перейти на Х12
INRL ;если было переполнение – увеличить счётчик переполнения
старшего байта на 1
X12: DCRB ;уменьшить кол-во циклов суммирования на 1
JNZX11 ;если цикл не последний – повторить суммирование
ADDH ;суммирование старшего байта множимого с счётчиком
переполнения младшего байта множимого
JNCX13 ;если нет переполнения – перейти на Х13
INRL ;если было переполнение – увеличить счётчик переполнения
старшего байта на 1
X13: STA 80FE ;отправить второй байт результата (Y) в ячейку ОЗУ 80FDH
MOVA, L ;переслать третий байт результата (Y) в аккумулятор
STA 80FF ;отправить третий байт (самый старший) результата (Y) в
ячейку ОЗУ 80FFH
RET ;выход из подпрограммы MULT
Задача #5
Разработать драйвер вывода информации (разрядностью 12 бит) на внешнее устройство с помощью параллельного интерфейса ППИ (К580ВВ55).
Поскольку разрядность данных составляет 12 бит, для их вывода понадобится порт А и порт В. Отправлять сигнал «Запись» и принимать сигнал «Готов» будем портом С. Следовательно, управляющее слово будет таким: 100010002 = 8816.
1 | 00 | 0 | 1 | 0 | 0 | 0 |
Режим работы группы А - 0 | Направление порта А - вывод | Направление порта С(7-4) - ввод | Группа В | Направление порта В - вывод | Направление порта С(3-0) - вывод |
Схема обмена данными ППИ с периферийным устройством:
Алгоритм работы драйвера:
DRV: PUSHB;сохранение с стеке пары ВС
PUSHD;сохранение с стеке пары DE
PUSHH;сохранение с стеке пары HL
PUSHPSW;сохранение с стеке аккумулятора и флагов
MVIA, 10001000
OUT <Пер. Устр.> ;вывод управляющего слова на периферийное устройство
LXIH, 8070 ;загрузка в пару HLадреса младшего байта
(1-8й бит) данных
MOVA, M
OUTPORTA;вывод младшего байта в порт А
INXH;перейти на адрес старшего байта (9-12й бит) данных
MOVA, M
OUTPORTB;вывод старшего байта в порт В
MVI A, 00000001
OUTPORTC;вывод сигнала «Запись» на порт С(0)
MVI A, 00000000
OUTPORTC;обнуление значения порта С
X1: INPORTC;приём сигнала портом С
RAL;перемещение старшего бита пришедшего сигнала
с порта С(7) в ТС
JNCX1 ;если ТС=0 (сигнал не пришёл) - продолжить ожидание
POPPSW;восстановление аккумулятора и флагов
POPH;восстановление пары HL
POPD;восстановление пары DE
POPB;восстановление пары BC
RET;выход из драйвера