Задача #1
Найти значение функции M3=(B+E-73H)+M2-(M1+7AH)-D
LDA 8150 ;M1→A
ADI 7A ;A:=A+7AH
MOV C, A ;A→C
LDA 8160 ;M2→A
SUB C ;A:=A-C
SUB D ;A:=A-D
MOV C, A ;A→C
MOV A, B ;B→A
ADD E ;A:=A+E
SUI 73 ;A:=A-73H
ADD C ;A:=A+C
STA 8170 ;A→M3
Задача #2
Написать алгоритм задержки 255 мс ± 0,1%
Поскольку 1 такт занимает 0,5 мкс, то по пропорции: | 1 такт - 0,5·10-6 сХ тактов - 255·10-3 с |
Учитывая погрешность 0,1%, результат должен составить 510000 ± 510 тактов.
Для такого кол-ва тактов будем использовать не один регистр, а регистровую пару DE.
Код задержки будет таким:
LXID, Y
CALL DEL
… … …
DEL: DCXD;5 тактов
MOVA, D;5 тактов
ORAD;4 такта
JNZDEL;10 тактов, если условие выполняется, и 7 тактов, если не выполняется
RET;10 тактов
Чтобы найти Yвоспользуемся формулой: 510000 = Y(5(DCX)+5(MOV)+4(ORA)+10(JNZ)) + 10(RET).
510000 = 24·Y + 10 → Y = (510000–10) / 24 → Y = 21249,58 ≈ 21250 циклов. 2125010 = 530216.
В программе использована команда ORAD, которая не влияет на содержимое аккумулятора, но влияет на флаг нулевого результата Z, по которому мы судим об окончании.
Окончательный код задержки будет выглядеть следующим образом:
LXID, 5302 ;10 тактов
CALLDEL;17 тактов
… … …
DEL: DCXD;5 тактов
MOVA, D;5 тактов
ORAD;4 такта
JNZDEL;10 тактов, если условие выполняется, и 7 тактов, если не выполняется
RET;10 тактов
В результате общее количество тактов будет: 24(один цикл)·21250 + 10(RET) – 3(JNZ) + 10(LXI) + 17(CALL) = 510034 тактов.
Погрешность составит:
.Задача #3
Вычислить , где АСР и АMIN– среднее арифметическое и минимальное значение массива однобайтных чисел объёмом в 64 элемента.
Значения АСР и АMINмогут быть в диапазоне:
. Следовательно, Yможет быть в диапазоне: . Как видно, результат умещается в один регистр (байт).Общий алгоритм программы выглядит так:
Алгоритм подпрограммы ADT (суммирования и нахождения минимального элемента):
Алгоритм подпрограммы DIV (деления через циклический сдвиг вправо с переносом):
Алгоритм подпрограммы REZ (нахождение значения Y):
<!-- так как среднее значение (АСР) не превышает один байт, то оно находится не в паре DE, а в регистре D; это значение будет переправлено в регистр Н (пара HL уже не используется), чтобы освободить пару DE -->
Листинг программы расположен ниже:
CALL ADT ;вызов подпрограммы ADT (суммирование и нахождение минимального
элемента)
MVI B, 06 ;задание кол-ва сдвигов (B:=06H – 6 сдвигов равносильно
делению на 64)
CALL DIV ;вызов подпрограммы DIV (нахождение среднего значения)
CALLREZ ;вызов подпрограммы REZ (вычисление результата Y)
STA 80FF ;пересылаем значение Y (окончательный результат) в ячейку 80FFH
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
REZ: MOV Н, D ;пересылаем среднее значение в регистр Н
LXI D, 0000 ;обнуление регистров E и D (пары DE) - старшего и младшего
байтов результата Y соответственно
MOVA, C ;пересылаем минимальное значение в аккумулятор (C→A)
ADD A ;суммирование (A:=AMIN+AMIN=2AMIN)
JNCX4 ;перейти на Х4 если нет переполнения
INRE ;произошло переполнение → прибавить 1 к старшему байту
результата Y
X4: ADDC ;суммирование (A:=2AMIN+AMIN=3AMIN)
JNCX5 ;перейти на Х5 если нет переполнения
INRE ;произошло переполнение → прибавить 1 к старшему байту
результата Y
X5: MOVD, A ;пересылаем младший байт из аккумулятора в регистр D
MVI B, 01 ;задание кол-ва сдвигов (B:=01H – 1 сдвиг равносилен
делению на 2)
CALL DIV ;вызов подпрограммы DIV (деление на 2)
MOVA, Н ;пересылаем среднее значение в аккумулятор (Н→A)
ADDD ;суммирование АСР + младший байт (3АMIN/2)
JNCX6 ;перейти на Х6 если нет переполнения
INRE ;произошло переполнение → прибавить 1 к старшему байту
результата Y
X6: MOVD, A ;пересылаем младший байт из аккумулятора в регистр D
MVI B, 02 ;задание кол-ва сдвигов (B:=02H – 2 сдвига равносильно
делению на 4)
CALL DIV ;вызов подпрограммы DIV (деление на 4)
MOVA, D ;пересылаем значение Y в регистр аккумулятор (D→A)
RET ;выход из подпрограммы REZ
Задача #4
Вычислить , где АСР, AMAX и АMIN– среднее арифметическое, максимальное и минимальное значение массива однобайтных чисел объёмом в 64 элемента.
Значения АСР, AMAX и АMINмогут быть в диапазоне:
. Минимальное значение (Y=00) может быть при АСР = AMAX = АMIN = 00. Максимальное значение будет тогда, когда массив будет состоять из 63х элементов, равных FF, и одного элемента, равного 00; при этом: AMAX = FF, АMIN = 00, АСР = FC. В таком случае значение Yсоставит 1F41016, что выходит за пределы пары регистров и умещается в три байта. Значение Yбудет располагаться в ячейках памяти 80FFH, 80FEH, 80FDH, причем младший байт – в ячейке 80FDH, самый старший – в ячейке 80FFH.Общий алгоритм программы выглядит так:
В программе используются подпрограммы ADT и DIV, алгоритм которых можно увидеть в задаче #3. Подпрограмма деления (DIV) идеально подходит и для задачи #4, а подпрограмму суммирования и нахождения минимального элемента массива (ADT) можно было бы дополнить нахождением и максимального элемента массива, если бы у на был хотя бы ещё один неиспользуемый регистр. Выйти из этой ситуации можно было бы используя ячейки ОЗУ для хранения промежуточных значений AMAX и АMIN. Но, так как AMAX требуется для расчёта лишь множителя, в программе была использована дополнительная подпрограмма нахождения максимального элемента и вычисления множителя (MAX).
Алгоритм подпрограммы REZ1 (вычисления множимого):