
- •«Разработка программ преобразования форматов двоичных данных и сортировок в машинных кодах микро-эвм см-1800 с помощью эмулятора на пк»
- •Задание
- •Содержание
- •Аналитическая часть
- •1.1 Двоично-десятичное кодирование
- •1.2 Операции двоично-десятичной арифметики
- •1.3 Кодирование текстовых данных
- •2 Практическая разработка
- •2.1 Блок – схема алгоритма
- •2.2 Распределение памяти и листинг программы с комментарием
- •2.3 Результаты тестирования программы
- •3 Описание использованных при проектировании средств вычислительной техники
2 Практическая разработка
Несмотря на то, что задана обработка массива и, следовательно, в программе будет цикл, возможны два подхода к составлению программы. В первом обработка очередного исходного значения и запись результата производится в основном цикле программы, во втором – для получения результата вызывается подпрограмма. Поскольку в примере из методического руководства рассматривался вариант с подпрограммой, реализуем для отличия вариант с получением результата в главном цикле программы, а версию с подпрограммой опишем в выводах.
2.1 Блок – схема алгоритма
Блок-схема приведена на рис. далее.
да
нет
нет
да
да
нет
2.2 Распределение памяти и листинг программы с комментарием
SP – адрес дна стека программы
C – счетчик цикла, также регистр C используется для хранения младшего байта
B – количество чисел, также регистр В используется для хранения старшего байта
H,L – текущий адрес элемента исходного массива
D,E – текущий адрес элемента результирующего массива
500016 – адрес начала массива исходных чисел
510016 – адрес начала массива результатов
Алгоритм в словесном описании выглядит так: установив указатели на адреса исходного массива данных и места для записи результатов, а также счетчик цикла, для каждого числа выполняем операции:
а) вычитаем по 100, пока не получим отрицательное число. Тем самым получаем старший байт результата (количество сотен);
б) восстановив полученное отрицательное число прибавлением 100, вычитаем по 10, пока не получим отрицательное число. Тем самым получаем количество десятков;
в) восстановив полученное отрицательное число прибавлением 10, получаем количество единиц;
г) сдвигаем кол-во десятков на 4 бита влево и логической операцией OR кладем в младшие 4 бита количество единиц;
д) записываем результат шагов «а)» и «(г)» в память и переходим к следующему числу.
Программа на языке ассемблера К-580 для решения задачи выглядит так:
ORG 4000h ; адрес размещения программы
LXI SP, A000h ; адрес стека
LXI H, 5000h ; адрес исходных данных
LXI D, 5100h ; адрес результатов
LXI B, 000Ah ; кол-во обрабатываемых чисел
LABEL6: PUSH B ; пара (BC) -> стек
MOV A, M ; взять очередное исходное число
MVI C, 00 ; обнулить счетчик для 1-го байта
LABEL2: SUI 64h ; (A) – 64h: вычитаем 100 (десятичное)
JC LABEL1 ; переход, если < 0
INR C ; иначе увеличиваем счетчик
JMP LABEL2 ; цикл
LABEL1: ADI 64h ; (A) + 64h: восстанавливаем значение
MOV B, C ; сохранили счетчик
MVI C, 00 ; и обнулили для 2-го байта
LABEL4: SUI 0Ah ; (A) – 0Ah: вычитаем 10 (десятичное)
JC LABEL3 ; переход, если < 0
INR C ; иначе увеличиваем счетчик
JMP LABEL4 ; цикл
LABEL3: ADI 0Ah ; (A) + 0Ah: восстанавливаем значение
PUSH PSW ; сохранить аккумулятор и флаги
MOV A, C ; (A) <- (C): записать десятки в (A)
MVI C, 04h ; повторить 4 раза
LABEL5: RLC ; сдвиг влево
DCR C ; уменьшить счетчик на 1
JNZ LABEL5 ; цикл, пока не сделано
MOV C, A ; (C) <- (A): перебросить в C
POP PSW ; восстановить аккумулятор и флаги
ORA C ; OR десятков и единиц
STAX D ; записать в память по адресу (DE)
INX D ; продвинуться к след. адресу
MOV A, B ; восстановить сотни
STAX D ; записать их в память
INX D ; продвинуться к след. адресу
INX H ; продвинуться к след. исх. числу
POP B ; восстанавливаем счетчик цикла
DCR C ; и уменьшаем его на 1
JNZ LABEL6 ; заново, если не все обработано
JMP 40h ; выход из программы в монитор
ORG 5000h ; адрес данных
SRCDATA DB 00h, 85h, 8Dh, 07h,Д 80h, 22h, D4h, A9h, FFh, A0h
ORG 5100h ; адрес результатов
DSTDATA DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h
Выполним ручную трансляцию программы:
Адрес |
Данные |
Ассемблерный код |
Комментарий |
4000 |
31 |
LXI SP,A000h |
Создание стека программы |
4001 |
00 |
||
4002 |
A0 |
||
4003 |
21 |
LXI H,5000h |
Загрузка в H,L адреса, начиная с которого будет считан массив исходных констант |
4004 |
00 |
||
4005 |
50 |
||
4006 |
11 |
LXI D,5100h |
Загрузка в пару D,E адреса, начиная с которого будет записан массив результатов |
4007 |
00 |
||
4008 |
51 |
||
4009 |
01 |
LXI B,000Ah |
Создание в регистре C счетчика цикла преобразования |
400A |
0A |
||
400B |
00 |
||
400C |
C5 |
PUSH B |
Сохранение в стек счетчика цикла |
400D |
7E |
MOV A,M |
Загрузка констант из памяти |
400E |
0E |
MVI C,00h |
Обнуление регистра C |
400F |
00 |
||
4010 |
D6 |
SUI 64h |
Вычитание из аккумулятора 6416 для получения старшего байта |
4011 |
64 |
||
4012 |
DA |
JC 4019h |
Если число станет меньше 6416, то перейти к восстановлению числа |
4013 |
19 |
||
4014 |
40 |
||
4015 |
0C |
INR C |
Положительное приращение регистра C |
4016 |
C3 |
JMP 4010h |
Переход к началу цикла |
4017 |
10 |
||
4018 |
40 |
||
4019 |
C6 |
ADI 64h |
Сложение аккумулятора с 6416 для восстановления значения при лишнем вычитании |
401A |
64 |
||
401B |
41 |
MOV B,C |
Сохранение аккумулятора в регистре C |
401C |
0E |
MVI C,00h |
Обнуление регистра C |
401D |
00 |
||
401E |
D6 |
SUI 0Ah |
Вычитание из аккумулятора 0A16 для получения младшего байта |
401F |
0A |
||
4020 |
DA |
JC 4027h |
Если число станет меньше 0A16, то перейти к восстановлению числа |
4021 |
27 |
||
4022 |
40 |
||
4023 |
0C |
INR C |
Положительное приращение регистра C |
4024 |
C3 |
JMP 401Eh |
Переход к началу цикла |
4025 |
1E |
||
4026 |
40 |
||
4027 |
C6 |
ADI 0Ah |
Сложение аккумулятора с 0A16 для восстановления значения при лишнем вычитании |
4028 |
0A |
||
4029 |
F5 |
PUSH PSW |
Сохранение аккумулятора и флагов |
402A |
79 |
MOV A,C |
Загрузка в аккумулятор из регистра C старшего байта двоично-десятичного кода |
402B |
0E |
MVI C,04h |
Занесение счетчика цикла |
402C |
04 |
||
402D |
07 |
RLC |
Сдвиг влево |
402E |
0D |
DCR C |
Уменьшение регистра C на 1 |
402F |
C2 |
JNZ 402Dh |
Переход по адресу 402Dh, если результат не равен 0 |
4030 |
2D |
||
4031 |
40 |
||
4032 |
4F |
MOV C,A |
Сохранение аккумулятора в регистре С |
4033 |
F1 |
POP PSW |
Восстановить аккумулятор и флаги |
4034 |
B1 |
ORA C |
Логическое сложение аккумулятора и регистра C |
4035 |
12 |
STAX D |
Сохранение младшего байта двоично-десятичного числа |
4036 |
13 |
INX D |
Переход к следующему адресу записи |
4037 |
78 |
MOV A,B |
Загрузка в аккумулятор из регистра B старшего байта двоично-десятичного кода |
4038 |
12 |
STAX D |
Сохранение старшего байта двоично-десятичного числа |
4039 |
13 |
INX D |
Переход к следующему адресу записи |
403A |
23 |
INX H |
Переход к следующему адресу чтения |
403B |
C1 |
POP B |
Восстановление из стека счетчика цикла |
403C |
0D |
DCR C |
Отрицательное приращение регистра C – счетчика цикла |
403D |
C2 |
JNZ 400Ch |
Если счетчик достиг нуля, то программа завершена |
403E |
0C |
||
403F |
40 |
||
403D |
C3 |
JMP 40h |
Выход из программы в монитор |
403E |
40 |
||
403F |
00 |
||
… |
… |
… |
… |
5000 |
|
|
С этого адреса идут исходные данные |
… |
… |
… |
… |
5100 |
|
|
С этого адреса пишется результат |