Главная Учебники - Разные Лекции (разные) - часть 26
|
Задача #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·10-6
с Х
тактов - 255·10-3
с Учитывая погрешность 0,1%, результат должен составить 510000 ± 510 тактов. Для такого кол-ва тактов будем использовать не один регистр, а регистровую пару DE. Код задержки будет таким: LXI
D
,
Y
CALL DEL
… … …
DEL
:
DCX
D
;5 тактов MOV
A
,
D
;5 тактов ORA
D
;4 такта JNZ
DEL
;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, по которому мы судим об окончании. Окончательный код задержки будет выглядеть следующим образом: LXI
D
, 5302
;10 тактов CALL
DEL
;17 тактов … … …
DEL
:
DCX
D
;5 тактов MOV
A
,
D
;5 тактов ORA
D
;4 такта JNZ
DEL
;10 тактов, если условие выполняется, и 7 тактов, если не выполняется RET
;10 тактов В результате общее количество тактов будет: 24(один цикл)
·21250 + 10(
RET)
– 3(
JNZ)
+ 10(
LXI)
+ 17(
CALL)
= 510034 тактов. Погрешность составит: Задача
#3
Вычислить Значения АСР
и А
MIN
могут быть в диапазоне: Общий алгоритм программы выглядит так:
Алгоритм подпрограммы ADT (суммирования и нахождения минимального элемента):
Алгоритм подпрограммы DIV (деления через циклический сдвиг вправо с переносом):
Алгоритм подпрограммы REZ (нахождение значения Y): <!-- так как среднее значение (АСР
) не превышает один байт, то оно находится не в паре DE, а в регистре D; это значение будет переправлено в регистр Н (пара HL уже не используется), чтобы освободить пару DE -->
Листинг программы расположен ниже: CALL
ADT
;вызов подпрограммы ADT (суммирование и нахождение минимального элемента) MVI
B
, 06
;задание кол-ва сдвигов (B:=06H – 6 сдвигов равносильно делению на 64) CALL DIV
;вызов подпрограммы DIV (нахождение среднего значения) CALL
REZ
;вызов подпрограммы REZ (вычисление результата Y) STA
80
FF
;
пересылаем значение Y (окончательный результат) в ячейку 80FFH RST 1
;выход из программы ADT
: LXI H, 8100
;задание адреса первого элемента (HL:=8100H) MVI
B
, 40
;задание кол-ва элементов (B:=64D=40H) XRA A
;обнуление аккумулятора LX
I
D
, 0000
;обнуление регистров E и D (пары DE) – старшего и младшего байтов результата суммирования соответственно MOV
C
,
M
;
будем считать первый элемент минимальным (С:=M(HL)) X1:
MOV
A
, M
;переслать в аккумулятор текущий элемент (A:=M(HL)) CMP
C
;сравниваем содержимое аккумулятора с текущим наименьшим значением (A-C) JP
X
2
;при TS=0 (A-C≥0 → A≥C) переход на Х2 MOV
C
,
A
;если же TS=1 (A-C<0 → A<C), сделать текущий элемент наименьшим X
2:
ADD
D
;суммирование (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
:
MOV
A
,
E
;пересылаем старший байт в аккумулятор (E→A) RAR
;циклический сдвиг вправо через ТС MOV
E
,
A
;возврат в Е старшего байта MOV
A
,
D
;пересылаем младший байт в аккумулятор (D→A) RAR
;циклический сдвиг вправо через ТС MOV
D
,
A
;возврат в D младшего байта ORA
A
;обнуление флага переполнения (ТС:=0) DCR
B
;уменьшение счётчика кол-ва сдвигов на 1 (B:=B-1) JNZ
DIV
;если сдвиг не последний – продолжить RET
;выход из подпрограммы DIV REZ
:
MOV
Н,
D
;пересылаем среднее значение в регистр Н LX
I
D
, 0000
;обнуление регистров E и D (пары DE) - старшего и младшего байтов результата Y соответственно MOV
A
,
C
;
пересылаем минимальное значение в аккумулятор (C→A) ADD A
;суммирование (A:=AMIN
+AMIN
=2AMIN
) JNC
X
4
;перейти на Х4 если нет переполнения INR
E
;
произошло переполнение → прибавить 1 к старшему байту результата Y X
4:
ADD
C
;
суммирование (A:=2AMIN
+AMIN
=3AMIN
) JNC
X
5
;перейти на Х5 если нет переполнения INR
E
;
произошло переполнение → прибавить 1 к старшему байту результата Y X
5:
MOV
D
,
A
;пересылаем младший байт из аккумулятора в регистр D MVI
B
, 01
;задание кол-ва сдвигов (B:=01H – 1 сдвиг равносилен делению на 2) CALL DIV
;вызов подпрограммы DIV (деление на 2) MOV
A
, Н
;пересылаем среднее значение в аккумулятор (Н→A) ADD
D
;суммирование АСР
+ младший байт (3АMIN
/2) JNC
X
6
;перейти на Х6 если нет переполнения INR
E
;
произошло переполнение → прибавить 1 к старшему байту результата Y X
6:
MOV
D
,
A
;пересылаем младший байт из аккумулятора в регистр D MVI
B
, 02
;задание кол-ва сдвигов (B:=02H – 2 сдвига равносильно делению на 4) CALL DIV
;вызов подпрограммы DIV (деление на 4) MOV
A
,
D
;пересылаем значение Y в регистр аккумулятор (D→A) RET
;выход из подпрограммы REZ Задача
#4
Вычислить Значения АСР
, AMAX
и А
MIN
могут быть в диапазоне: Общий алгоритм программы выглядит так:
В программе используются подпрограммы ADT и DIV, алгоритм которых можно увидеть в задаче #3
. Подпрограмма деления (DIV) идеально подходит и для задачи #4
, а подпрограмму суммирования и нахождения минимального элемента массива (ADT) можно было бы дополнить нахождением и максимального элемента массива, если бы у на был хотя бы ещё один неиспользуемый регистр. Выйти из этой ситуации можно было бы используя ячейки ОЗУ для хранения промежуточных значений AMAX
и А
MIN
. Но, так как AMAX
требуется для расчёта лишь множителя, в программе была использована дополнительная подпрограмма нахождения максимального элемента и вычисления множителя (MAX). Алгоритм подпрограммы REZ1 (вычисления множимого):
Алгоритм подпрограммы 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 (нахождение среднего значения) CALL
REZ
1
;вызов подпрограммы REZ1 (вычисление (4ACP
– AMIN
/4)) CALL
MAX
;вызов подпрограммы MAX (вычисление AMAX
/2) CALL
MULT
;вызов подпрограммы MULT (умножение) RST 1
;выход из программы ADT
: LXI H, 8100
;задание адреса первого элемента (HL:=8100H) MVI
B
, 40
;задание кол-ва элементов (B:=64D=40H) XRA A
;обнуление аккумулятора LX
I
D
, 0000
;обнуление регистров E и D (пары DE) – старшего и младшего байтов результата суммирования соответственно MOV
C
,
M
;
будем считать первый элемент минимальным (С:=M(HL)) X1:
MOV
A
, M
;переслать в аккумулятор текущий элемент (A:=M(HL)) CMP
C
;сравниваем содержимое аккумулятора с текущим наименьшим значением (A-C) JP
X
2
;при TS=0 (A-C≥0 → A≥C) переход на Х2 MOV
C
,
A
;если же TS=1 (A-C<0 → A<C), сделать текущий элемент наименьшим X
2:
ADD
D
;суммирование (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
:
MOV
A
,
E
;пересылаем старший байт в аккумулятор (E→A) RAR
;циклический сдвиг вправо через ТС MOV
E
,
A
;возврат в Е старшего байта MOV
A
,
D
;пересылаем младший байт в аккумулятор (D→A) RAR
;циклический сдвиг вправо через ТС MOV
D
,
A
;возврат в D младшего байта ORA
A
;обнуление флага переполнения (ТС:=0) DCR
B
;уменьшение счётчика кол-ва сдвигов на 1 (B:=B-1) JNZ
DIV
;если сдвиг не последний – продолжить RET
;выход из подпрограммы DIV REZ
1:
MOV
Н,
D
;пересылаем ACP
в регистр Н MVI
E
, 00 ;
обнуление регистра Е MOV
D
,
C
;
пересылка АMIN
в регистр D MVI
B
, 02
;задание кол-ва сдвигов (B:=02H – 2 сдвигa равносильно делению на 4) CALL DIV
;вызов подпрограммы DIV (деление на 4) MOV
C
,
D
;обратная пересылка в регистр С значения АMIN
/4 MOV
A
,
H
;
отправляем ACP
в аккумулятор MVI
E
, 00 ;
обнуление регистра E MVI
B
, 03 ;
записываем в регистр В количество циклов суммирования (03 = 4 - 1) X
4:
ADD
H
;
к аккумулятору прибавляем по одному значению ACP
JNC
X
5 ;
если нет переполнения – перейти на Х5 INR
E
;
если произошло переполнение – увеличить старший байт на 1 X
5:
DCR
B
;
уменьшить кол-во циклов суммирования на 1 JNZ
X
4 ;
если цикл не последний – повторить суммирование SUB
C
;
вычитание: 4АСР
– AMIN
/4 JP
X
6 ;
если результат вычитания положителен – перейти на Х6 DCR
E
;
если результат вычитания отрицателен – вычесть 1 из старшего байта X
6:
MOV
D
,
A
;
переслать младший байт результата (4АСР
– AMIN
/4) в регистр D (весь результат находится в паре DE) RET
;выход из подпрограммы REZ1 MAX
: LXI H, 8100
;задание адреса первого элемента (HL:=8100H) MVI
B
, 40
;задание кол-ва элементов (B:=64D=40H) MOV
A
,
M
;
будем считать первый элемент максимальным (A:=M(HL)) X7:
CMP
M
;сравниваем максимальный элемент с текущим (A-M(HL)) JP
X
8
;при TS=0 (A-M(HL)≥0 → A≥M(HL)) переход на Х8 MOV
A
,
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 ORA
A
;обнуление флага переполнения (ТС:=0) MOV
C
,
A
;пересылка значения AMAX
/2 в регистр C RET
;выход из подпрограммы MAX MULT
:
LXI
H
, 0000 ;
обнуление регистров H и L MOV
B
,
C
;загрузить множитель (AMAX
/2) в регистр В DCR
B
;уменьшение на 1 множителя MOV
A
,
D
;пересылка младшего байта множимого в аккумулятор X
9:
ADD
D
;суммируем по одному значению JNC
X
10
;если нет переполнения – перейти на Х10 INR
H
;если было переполнение – увеличить счётчик переполнения младшего байта на 1 X
10:
DCR
B
;уменьшить кол-во циклов суммирования на 1 JNZ
X
9
;если цикл не последний – повторить суммирование STA
80
FD
;отправить первый (самый младший) байт результата (Y) в ячейку ОЗУ 80FDH MOV
B
,
C
;загрузить множитель (AMAX
/2) в регистр В DCR
B
;уменьшение на 1 множителя MOV
A
,
E
;пересылка старшего байта множимого в аккумулятор X
11:
ADD
E
;суммируем по одному значению JNC
X
12
;если нет переполнения – перейти на Х12 INR
L
;если было переполнение – увеличить счётчик переполнения старшего байта на 1 X
12:
DCR
B
;уменьшить кол-во циклов суммирования на 1 JNZ
X
11
;если цикл не последний – повторить суммирование ADD
H
;суммирование старшего байта множимого с счётчиком переполнения младшего байта множимого JNC
X
13
;если нет переполнения – перейти на Х13 INR
L
;если было переполнение – увеличить счётчик переполнения старшего байта на 1 X
13:
STA
80
FE
;отправить второй байт результата (Y) в ячейку ОЗУ 80FDH MOV
A
,
L
;переслать третий байт результата (Y) в аккумулятор STA
80
FF
;отправить третий байт (самый старший) результата (Y) в ячейку ОЗУ 80FFH RET
;выход из подпрограммы MULT Задача
#5
Разработать драйвер вывода информации (разрядностью 12 бит) на внешнее устройство с помощью параллельного интерфейса ППИ (К580ВВ55). Поскольку разрядность данных составляет 12 бит, для их вывода понадобится порт А и порт В. Отправлять сигнал «Запись» и принимать сигнал «Готов» будем портом С. Следовательно, управляющее слово будет таким: 100010002
= 8816
. Схема обмена данными ППИ с периферийным устройством:
Алгоритм работы драйвера:
DRV
:
PUSH
B
;сохранение с стеке пары ВС PUSH
D
;сохранение с стеке пары DE PUSH
H
;сохранение с стеке пары HL PUSH
PSW
;сохранение с стеке аккумулятора и флагов MVI
A
, 10001000
OUT
<
П
ер.
У
стр.>
;вывод управляющего слова на периферийное устройство LXI
H
, 8070
;загрузка в пару HLадреса младшего байта (1-8й бит) данных MOV
A
,
M
OUT
PORTA
;вывод младшего байта в порт А INX
H
;перейти на адрес старшего байта (9-12й бит) данных MOV
A
,
M
OUT
PORTB
;вывод старшего байта в порт В MVI A, 00000001
OUT
PORTC
;вывод сигнала «Запись» на порт С(0) MVI A, 00000000
OUT
PORTC
;обнуление значения порта С X
1:
IN
PORTC
;приём сигнала портом С RAL
;перемещение старшего бита пришедшего сигнала с порта С(7) в ТС JNC
X
1
;если ТС=0 (сигнал не пришёл) - продолжить ожидание POP
PSW
;восстановление аккумулятора и флагов POP
H
;восстановление пары HL POP
D
;восстановление пары DE POP
B
;восстановление пары BC RET
| ||||||||||||||||||||