Скачать .docx |
Реферат: Асемблер Контрольна - вар1
Задача #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.
Код задержки будет таким:
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 – среднее арифметическое и минимальное значение массива однобайтных чисел объёмом в 64 элемента.
Значения АСР и А MIN могут быть в диапазоне: . Следовательно, Y может быть в диапазоне: . Как видно, результат умещается в один регистр (байт).
Общий алгоритм программы выглядит так:
Алгоритм подпрограммы 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 – среднее арифметическое, максимальное и минимальное значение массива однобайтных чисел объёмом в 64 элемента.
Значения АСР , AMAX и А MIN могут быть в диапазоне: . Минимальное значение (Y=00 ) может быть при АСР = AMAX = А MIN = 00. Максимальное значение будет тогда, когда массив будет состоять из 63х элементов, равных FF , и одного элемента, равного 00 ; при этом: AMAX = FF , А MIN = 00 , АСР = FC . В таком случае значение Y составит 1 F41016 , что выходит за пределы пары регистров и умещается в три байта. Значение Y будет располагаться в ячейках памяти 80 FFH , 80 FEH , 80 FDH, причем младший байт – в ячейке 80 FDH , самый старший – в ячейке 80 FFH .
Общий алгоритм программы выглядит так:
В программе используются подпрограммы 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 .
1 | 00 | 0 | 1 | 0 | 0 | 0 |
Режим работы группы А - 0 | Направление порта А - вывод | Направление порта С(7-4) - ввод | Группа В | Направление порта В - вывод | Направление порта С(3-0) - вывод |
Схема обмена данными ППИ с периферийным устройством:
Алгоритм работы драйвера:
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 ;выход из драйвера