Цель работы: изучение способов организации и исследование программ выполнения арифметических операций.
Из двух способов представления чисел с фиксированной и плавающей точкой первый получил наибольшее распространение при программировании микроЭВМ на МП i8080A. Это связано с отсутствием специальных команд, позволяющих работать МП с числами с плавающей точкой. В свою очередь, двоичное восьмиразрядное число с фиксированной точкой можно представить как двоичное число со знаком, имеющее значение от -128d до +127d. При этом отрицательные числа представляются в дополнительном коде, а старший, седьмой разряд числа используется как знаковый. Такое представление чисел не позволяет выполнять арифметические операции с использованием переноса при сложении и заёма при вычитании.
Число с фиксированной точкой можно представлять также двоичными числами без знака, имеющими значения от 0 до 255d.
Для МП i8080A можно представлять также такие числа в виде двоично-десятичного числа - BINARY-CODED-DECIMAL (BCD), при котором каждый байт рассматривается как два полубайта - две тетрады, каждая из которых кодирует десятичную цифру. Такое представление позволяет закодировать в 1 байт числа от 0 до 99d.
Проведение арифметических операций сложения, вычитания, умножения, деления, вычисления специальных функций рассмотрим на примерах соответствующих программ.
Программа сложения массива однобайтных чисел с получением двухбайтного результата - программа MAIN (программа 16). Слагаемые должны быть расположены в последовательных адресах памяти. Входными параметрами с подпрограммы ADD B являются адрес первого слагаемого, записанный в регистрах H, L и число слагаемых, записанное в регистре B. Выходным параметром программы MAIN является сумма, старший байт которой записан в регистре C, а младший - в аккумуляторе A.
Программа 16
Адрес
|
Код
|
Метка
|
Мнемокод
|
Комментарий
|
800
|
21 00 0C
|
MAIN:
|
LXI H,0C00h
|
; Записать в регистры H, L адрес первого
; слагаемого
|
0803
|
06 05
|
|
MVI B, 05h
|
; Загрузить в регистр B количество
; слагаемых
|
0805
|
CD 09 08
|
|
CALL ADDB
|
; Вызвать подпрограмму сложения
|
0808
|
CF
|
|
RST 1
|
; Прервать программу
|
0809
|
AF
|
ADDB:
|
XRA A
|
; Очистить аккумулятор
|
080A
|
4F
|
|
MOV C, A
|
; Очистить счетчик переносов
|
080B
|
86
|
CNT:
|
ADD M
|
; Прибавить к содержимому A число из
; массива слагаемых
|
080C
|
D2 10 08
|
|
JNC TRM
|
; Если переноса нет, то идти на TRM
|
080F
|
0C
|
|
INR C
|
; Увеличить содержимое регистра C на 1
|
0810
|
23
|
TRM:
|
INX H
|
; Указать на следующий адрес слагаемого
|
0811
|
05
|
|
DCR B
|
; Уменьшить содержимое счетчика
; слагаемых
|
0812
|
C2 0B 08
|
|
JNZ CNT
|
;Если не все слагаемые, то идти на CNT
|
0815
|
C9
|
|
RET
|
|
Алгоритм программы сложения состоит в том, что после прибавления каждого элемента массива определяется переполнение аккумулятора (разряд CY =1), и если это имеет место, то содержимое регистра C увеличивается на 1. Таким образом, за счет суммирования единиц переноса получается старший байт суммы (рис. 4, а).
Рис. 4. Алгоритм подпрограммы сложения (а) и умножения (б)
МикроЭВМ может проводить арифметические операции с числами с двойной или большей длиной машинного слова. Так как МП имеет 8-разрядное АЛУ, то операции с такими числами должны проводиться по байтам начиная с младших байтов. Так, операция сложения чисел 17F5h + 3411h будет проводиться в следующем виде:
Старший байт Флаг CY Младший байт Числа
00101111b 11110101b 17F5h
+ + +
00110100b 00010001b 3411h
+ 1 <- 1
01001100b 00000110b 4C06h
Операция вычитания чисел 6F5C - 13C5 будет осуществляться в таком виде:
Старший байт
|
Флаг CY
|
Младший байт
|
Числа
|
01101111b
|
|
01011100b
|
6F5Ch
|
-
|
|
-
|
—
|
00010011b
|
|
11000101b
|
13C5h
|
-1
|
<- 1
|
|
|
01011011b
|
|
10010111b
|
5В97h
|
Из приведенных примеров видно, что при суммировании (вычитании) младших байтов чисел необходимо применять команду ADD (SUB), а для сложения (вычитания) остальных - команду ADC (SBB), которая будет учитывать состояние разряда CY регистра признаков МП.
Программа нахождения разности чисел, имеющих одинаковую длину, - программа 17. Входные параметры: регистр C - длина чисел (в байтах), регистры H, L - адрес младшего байта вычитаемого, регистры D, E - адрес младшего байта уменьшаемого. Каждое из чисел записывается в последовательных адресах памяти, начиная с младших байтов. Результат заносится в область памяти, отведенную под вычитаемое.
Программа 17
Адрес
|
Код
|
Метка
|
Мнемокод
|
Комментарий
|
0900
|
AF
|
SBN:
|
XRA A
|
; Очистить аккумулятор и флаг CY
|
0901
|
1A
|
CNT:
|
LDAX D
|
; Записать в аккумулятор уменьшаемое
|
0902
|
9E
|
|
SBB M
|
; Вычесть из содержимого аккумулятора
; вычитаемое
|
0903
|
77
|
|
MOV M, А
|
; Записать разность на место вычитаемого
|
0904
|
23
|
|
INX H
|
; Указать на следующий байт вычитаемого
|
0905
|
13
|
|
INX D
|
; Указать на следующий байт уменьшаемого
|
0906
|
0D
|
|
DCR C
|
; Уменьшить содержимое счетчика длины
; числа
|
0907
|
C2 01 09
|
|
JNZ CNT
|
; Если не последний (старший байт числа),
; то идти на CNT
|
090A
|
D0
|
|
RNC
|
; Если байт старший и результат без заёма
; (CY = 0), то возврат
|
090B
|
CF
|
|
RST 1
|
; Прервать выполнение программы
|
Умножение чисел. Существует несколько алгоритмов умножения чисел. При первом алгоритме умножение можно заменить многократным сложением, например 14 х 3 = 14 + 14 + 14. Существенный недостаток этого способа - значительная длительность процесса вычисления. При втором алгоритме умножение осуществляется в столбец. Этот алгоритм применим и для умножения двоичных чисел, например:
0110 = 6d
0011 = 3d
0110
0110
0000
0000
00010010 = 18d
При вычислении результата по второму алгоритму необходимо осуществить многократное суммирование со сдвигом влево множимого при одновременной проверке содержимого разрядов множителя, начиная со стороны его младшего разряда. При этом если в очередном разряде множителя записана 1, то множимое прибавляется к сумме и сдвигается влево на один разряд, а если в разряде записан 0, то произойдет только сдвиг множимого. Сдвиг множимого влево можно заменить сдвигом суммы вправо. По этому алгоритму (рис. 4, б) работает программа умножения двух однобайтных чисел с получением двухбайтного результата (программа 18). Начальный адрес подпрограммы - 04Е1Н; входные параметры: регистр D - множимое, регистр Е - множитель. Результат перемножения записывается в регистры B, С.
Программа 18
Адрес
|
Код
|
Метка
|
Мнемокод
|
Комментарий
|
0900
|
01 00 00
|
MPL:
|
LXI B, 0000h
|
;Очистить содержимое регистров B, С
|
0903
|
3Е 01
|
|
MVI A, 01h
|
; Загрузить в аккумулятор указатель
; разряда
|
0905
|
A7
|
|
ANA A
|
; Очистить флаг CY
|
0906
|
F5
|
MPL1:
|
PUSH PSW
|
; Сохранить указатель разряда в стеке
|
0907
|
A3
|
|
ANA E
|
; Проверить содержимое очередного
; разряда множителя
|
0908
|
78
|
|
MOV A, В
|
; Загрузить в аккумулятор старший байт
; суммы
|
0909
|
CA ЕЕ 04
|
|
JZ MPL2
|
; Если в очередном разряде записан 0,
; идти на MPL2
|
090C
|
82
|
|
ADD D
|
; Прибавить множимое к сумме
|
090D
|
1F
|
MPL2:
|
RAR
|
; Сдвинуть сумму вправо
; (младший бит -> CY)
|
090E
|
47
|
|
MOV B, А
|
; Сохранить содержимое аккумулятора в
; регистре B
|
090F
|
79
|
|
MOV A, С
|
; Загрузить в аккумулятор младший байт
; суммы
|
0910
|
1F
|
|
RAR
|
; Сдвинуть число в аккумуляторе вправо
; (CY -> старший бит)
|
0911
|
4F
|
|
MOV C, A
|
; Со хранить содержимое аккумулятора в
; регистре C
|
0912
|
F1
|
|
POP PSW
|
; Получить из стека указатель разряда
|
0913
|
17
|
|
RAL
|
; Указатель на следующий разряд
|
0914
|
D2 E7 04
|
|
JNC MPL1
|
; Если разряд не последний, продолжать
; на MPL1
|
0917
|
C9
|
|
RET
|
; Если разряд последний, возврат
|
Деление чисел. Деление двоичных чисел, как и чисел представленных в любой другой системе счисления, основывается последовательном вычитании делителя из делимого и остатков деления. Однако, двоичное деление реализуется проще, так к использование только двух цифр (0 и 1) исключает в каждом цикле деления необходимость определения числа делителей, содержащихся текущем значении делимого или остатка (достаточно только сравни их).
Схема алгоритма деления двоичных чисел приведена рис. 5. Программа DIVB построена по этому алгоритму (программа 19). Входными параметрами этой программы являют делимое (в регистре В) и делитель (в регистре D); выходными параметрами - частное (в регистре Н) и остаток (в регистре С).
Рис. 5. Схема, алгоритма подпрограммы деления двух восьмиразрядных чисел
Программа 19
Адрес
|
Код
|
Метка
|
Мнемокод
|
Комментарий
|
0900
|
21 08 00
|
DIVB:
|
LXI H, 0008h
|
; Загрузить счетчик битов регистр L и
; очистить регистр частного H
|
0903
|
0E 00
|
|
MVI C,00h
|
; Очистить регистр промежуточного
; делимого
|
0905
|
7B
|
MXTB:
|
MOV A, E
|
; Загрузить делимое в аккумулятор
|
0906
|
17
|
|
RAL
|
; Сдвинуть старший бит в разряд CY
|
0907
|
5F
|
|
MOV E, А
|
; Возвратить делимое в регистр E
|
0908
|
79
|
|
MOV A, С
|
; Загрузить в аккумулятор промежуточное
; делимое из регистра C
|
0909
|
17
|
|
RAL
|
; Сдвинуть разряд CY в младший бит
|
090A
|
92
|
|
SUB D
|
; Вычесть из содержимого аккумулятора
; делитель
|
090B
|
D2 0F 09
|
|
JNC NOADD
|
; Если CY = 1 восстановить содержимое
; аккумулятора
|
090E
|
82
|
|
ADD D
|
|
090F
|
4F
|
NOADD:
|
MOV C, А
|
; Возвратить промежуточное данное в
; регистр C
|
0910
|
3F
|
|
CMC
|
; Инвертировать разряд CY
|
0911
|
7C
|
|
MOV A, H
|
; Сдвинуть разряд CY в младший бит
; регистра частного Н
|
0912
|
17
|
|
RAL
|
; Проверены ли все
|
0913
|
67
|
|
MOV H,A
|
; восемь
|
0914
|
2D
|
|
DCR L
|
; разрядов?
|
0915
|
C2 05 09
|
|
JNZ MXTB
|
; Если нет, продолжать
|
0918
|
CF
|
|
RST 1
|
; Если да, прервать выполнение программы
|
Вычисление специальных функций. Для вычисления специальных функций (sin x, cos x, tg x, ln x и т. д.) применяются специальные алгоритмы. Функции sin x, cos x, In x можно вычислить, воспользовавшись их разложением в ряд. Число ряда определяется из условия получения требуемой точности.
Вычисление специальных функций с помощью разложения в ряд занимает длительное время и обеспечивает низкую точность. Это обусловлено сравнительно небольшой длиной машинного слова и ограниченным быстродействием МП. Поэтому в тех случаях, когда ставятся жесткие требования по быстродействию и точности, применяется вычисление функций с помощью таблиц. Проиллюстрируем этот метод на примере программы вычисления квадрата числа x (программа 20).
Программа SQ определяет квадрат десятичных чисел от 0 до 10 включительно. Входной параметр программы - число x. Оно записывается в регистр L. Выходной параметр - значение в регистре H.
Программа 20
Адрес
|
Код
|
Метка
|
Мнемокод
|
Комментарий
|
0900
|
26 00
|
SQ:
|
MVI H, 00h
|
; Очистить регистр H
|
0902
|
11 00 0A
|
|
LXI D, SQTB
|
; Загрузить начальный адрес таблицы
|
0905
|
19
|
|
DAD D
|
; Получить адрес элемента
|
0906
|
66
|
|
MOV H, M
|
; Загрузить его в регистр H
|
0907
|
CF
|
|
RST 1
|
; Прервать выполнение программы
|
0A00
|
00
|
SQTB:
|
00h
|
; Таблица квадратов
|
0A01
|
01
|
|
01h
|
; чисел от 0 до А
|
0A02
|
04
|
|
04h
|
; включительно в
|
0A03
|
09
|
|
09h
|
; шестнадцатеричном
|
0A04
|
10
|
|
10h
|
; коде
|
0A05
|
19
|
|
19h
|
|
0A06
|
24
|
|
24h
|
|
0A07
|
31
|
|
31h
|
|
0A08
|
40
|
|
40h
|
|
0A09
|
51
|
|
51h
|
|
0A0A
|
64
|
|
64h
|
|
Задания
1. Изучите группу арифметических команд МП KP580BM80.
2. Изучите программы 16 - 20, приведенные выше.
3. Исследуйте программу сложения однобайтных чисел с получением двухбайтного результата.
3.1. Введите в микроЭВМ программу 16.
3.2. Запишите в микроЭВМ последовательность из пяти чисел начиная с адреса 0C00h. 3.3. Осуществите пуск программы и проверьте ее выполнение по данным, записанным в регистре C и аккумуляторе МП.
3.4. Измените программу 16 так, чтобы результат выполнения записывался по адресу 0C06h и 0CB07h. Проверьте результат ее выполнения.
3.5. Измените в программе указатель количества слагаемых в сумме и выполните программу заново.
4. Исследуйте программу вычитания двух чисел, имеющих одинаковую длину.
4.1. Введите программу 17 в микроЭВМ.
4.2. Запишите в регистры D, E и H, L соответственно начальные адреса младших байтов уменьшаемого и вычитаемого. Вычитаемое должно быть записано в области ОЗУ, где нет защиты от случайной записи во время выполнения программ (в учебной микроЭВМ эта область занимает адреса 0C00h - 0FB0h). Запишите в регистр C число 01h (рассматривается вычитание двух 8-разрядных чисел).
4.3. Запишите по адресам, указанным в регистрах H, L и D, L уменьшаемое и вычитаемое.
4.4. Осуществите пуск программы 17 и исследуйте результат ее выполнения по числу, записанному по адресу, где записано вычитаемое.
4.5. Видоизмените программу 18 так, чтобы результат вычитания разности двух 8-разрядных чисел записывался в выходное устройство с адресом 05h.
4.6. Измените числа, записанные по адресам, указанным в регистрах H, L и D, E, так чтобы уменьшаемое было меньше вычитаемого.
4.7. Осуществите пуск программы и проследите, что при этом получается.
4.8. Исследуйте в аналогичной последовательности результат вычитания двухбайтных чисел.
5. Исследуйте программу умножения двух 8-разрядных чисел с получением 16-разрядного результата.
5.1. Введите в микроЭВМ программу для исследования результата перемножения двух чисел, разработанную самостоятельно.
5.2. Осуществите пуск программы и проверьте результат перемножения двух чисел по числу, записанному в регистрах B, C.
6. Исследуйте программу деления двух 8-разрядных чисел.
6.1. Введите в микроЭВМ программу 19.
6.2. Запишите в регистры E, D соответственно делимое и делитель.
6.3. Осуществите пуск программы и проверьте результат деления двух чисел по содержимому регистров H, С.
7. Исследуйте программу вычисления квадрата числа с помощью таблицы.
7.1. Введите в микроЭВМ программу 20.
7.2. Запишите в регистр L число, квадрат которого необходимо вычислить.
7.3. Осуществите пуск программы и проверьте результат вычисления квадрата числа по содержимому регистра H.
7.4. Видоизмените программу так, чтобы результат вычисления квадрата числа записывался в выходное устройство.
7.5. Введите в программу 20 проверку на значение числа, квадрат которого определяется в результате выполнения программы. Если задаваемое число больше 10d, то микроЭВМ должна указывать на это, например, включением светодиодов выходного устройства и т. д.
|