Курсовая работа: Микропроцессорная система управления, предназначенная для использования на лесопильном заводе
Сложение
В микропроцессоре Z80
есть команда сложения регистровых пар ADD HL, DE. Однако, чтобы сохранить
единообразие, оформим ее все же как подпрограмму.
Листинг 8: подпрограмма PLUS
; – – – подпрограмма
сложения
; HL+DE®HL
; сохраняет A, BC, DE
PLUS ADD HL,
DE ;
RET ;
Вычитание
В Z80 есть команда
вычитания регистровых пар с учетом переноса SBC HL, DE. Используем ее в
подпрограмме вычитания, обнулив прежде флаг CY.
Листинг 9: подпрограмма MINUS
; – – – подпрограмма
сложения
; HL–DE®HL
; сохраняет A, BC, DE
MINUS OR A ;
A не меняется, но флаг CY=0
SBC HL, DE ;
RET ;
Умножение
При умножении первый
множитель хранится в паре BC (скопируем его туда из HL в начале), второй
множитель хранится в DE. Результат первоначально получается в четырехбайтном
виде HL.DE, затем “обрезается” до H.L.
Результат произведения накапливается
в HLDE. В течение 16 циклов сдвигов HLDE второй множитель DE постепенно
выдвигаясь, уходит вправо и на его место приходит из HL готовые биты
произведения. Они получаются при суммировании первого множителя (BC) и левой
половины накопленной суммы HLDE (HL). Суммирование делается в случае, если
перед этим при сдвиге HLDE вправо из DE был выдвинут единичный бит.
Листинг 10: подпрограмма MUL
; – – – подпрограмма
умножения
; HL´DE®HL
; все регистры меняются
MUL LD B, H ;
BC=1-й множитель
LD C, L ;
LD HL, 0 ;
HL=0
LD A, 16 ;
счетчик цикла
MUL2 SRL H ;
сдвиг 0®HLDE®CY
RR L ;
RR D ;
RR E ;
JR NC, MUL1 ; если
выдвинут 0, то на конец цикла
ADD HL, BC ;
если выдвинута 1, то сложить
MUL1 DEC A ;
JR NZ,
MUL2 ;
LD H, L ;
получено произведение HL.DE
LD L, D ;
которое “обрезаем” до L.D и переносим в H.L
RET
Деление
При делении делимое
хранится в HL, делитель в DE. Результат получается в виде трех байт [стек.L]
(где “стек” – содержимое вершины стека), в конце программы младший байт стека
переносится в H и окончательный результат имеет формат H.L. Регистровая пара BC
в начале обнуляется.
Деление производится в
течение 24-х циклов. В каждом цикле делается сдвиг BC¬HL¬0, т.е. делимое HL выдвигается влево в пару BC. Затем BC
сравнивается с DE (путем вычитания BC–DE и проверки флага переноса). Если
BC>DE, то младший разряд HL устанавливается единицей, в противном случае он
остается нулем. Это один из разрядов частного.
После 16 сдвигов в
делимое HL полностью сдвинется влево и на его место придет частное
целочисленного деления, в BC будет остаток деления, DE сохранит делитель. На этом
этапе целая часть частного в HL заносится в стек, а HL обнуляется. В оставшихся
8-ми сдвигах BC¬HL
в BC будут сдвигаться только нули. После всех 24-х циклов в регистре L будет
дробная часть частного, а в стеке целая часть.
Листинг 11: подпрограмма DIV
; – – – подпрограмма
деления
; HL/DE®HL
; сохраняет DE,
использует стек (2 байта)
DIV LD BC, 0 ;
LD A, 24 ; А
– счетчик циклов
DIV4 PUSH AF ;
сохранить счетчик А в стеке
ADD HL, HL ;
BC¬HL¬0
RL C ;
RL B ;
LD A,
C ;
SUB E ;
LD C,
A ;
LD A,
B ;
SBC D ;
LD B,
A ;
JR NC,
DIV1 ; если BC>DE, то переход
LD A, C ;
ADD E ;
LD C,
A ;
LD A,
B ;
ADC D ;
LD B,
A ;
JR DIV2 ;
DIV1 INC HL ;
если BC>DE: установить последний бит
;
частного в 1
DIV2 POP AF ;
извлечь счетчик А из стека
CP #09 ;
проверить, 16-й цикл идет или нет
JR NZ, DIV3 ;
PUSH HL ;
если 16-й цикл, то в HL целая часть частного,
;
сохранить ее в стеке, чтобы извлечь
;
в конце программы
LD HL,
0 ;
DIV3 DEC A ;
JR NZ,
DIV4 ; конец цикла
POP BC ;
извлекаем из стека целую часть частного
LD H,
C ; получаем частное в H.L
RET ;
Косинус
Чтобы вычислить косинус,
используется ограниченный четырьмя членами ряд Тейлора:
, угол a изменяется от 0 до p/2. (6)
Эта формула дает косинус
с максимальной погрешностью 8,9×10-4, это меньше, чем ошибка разрядности
используемого формата [1].[1] дробных чисел.
(7)
Представление (7) формулы
(6) гораздо удобнее для вычисления косинуса программно. Достаточно сделать
процедуру для вычисления , где n
– целое число, b
– дробное число. Перед обращением к этой процедуре (названной COS_A) операнды
содержатся:
HL = a2;
DE = b;
BC = n в формате n.0
(B=n, C=0).
Результат – в HL
Эта подпрограмма
использует предыдущие арифметические программы.
Листинг 12: подпрограмма COS_A
; – – – вспомогательная
подпрограмма для косинуса
; операнды: HL, DE, BC
; изменяются все регистры
COS_A PUSH BC ;
сохранить в стеке n перед вызовом MUL
CALL MUL ;
HL=HL´DE
POP DE ;
DE=n
CALL DIV ;
HL=HL/DE
LD D, 1 ;
DE=1.0
LD E, 0 ;
EX HL, DE ;
CALL MINUS ;
HL=HL-DE
RET ;
Подпрограмма косинуса
вычисляет косинус угла в паре HL.
Листинг 13: подпрограмма COS
; – – –подпрограмма
косинуса
; операнд и результат в
HL
; изменяются все регистры
COS LD D,
H ;
LD E, L ;
CALL MUL ;
HL=a2
PUSH HL ;
a2 в стеке
LD D,
1 ; DE=1.0
LD E,
0 ;
LD B,
#1E ; BC=1E.0H=30
LD C,
0 ;
CALL COS_A ;
HL=1-a2/30
EX HL,
DE ;
POP HL ;
HL=a2
PUSH HL ;
a2 в стеке
LD B,
#0C ; BC=C.0H=12
LD C,
0 ;
CALL COS_A ;
HL=1-a2/12(1-a2/30)
EX HL,
DE ;
POP HL ;
HL=a2
LD B,
#02 ; BC=2.0
LD C,
0 ;
CALL COS_A ;
HL=1-a2/2[1-a2/12(1-a2/30)]
RET ;
Преобразование
двоичный®двоично-десятичный код
В управляющей программе
надо переводить двухбайтные числа формата [12].[34] в двоично-десятичный код
вида [123.45] размером в пять тетрад для последующего перевода в семисегментный
код и индикации.
Для этого нужны две
отдельных подпрограммы: одна (по имени B2D) для перевода целой части числа [12]
и вторая (имя B2D_F) для перевода дробной части числа [34].
Подпрограмма B2D
переводит целое двоичное число в регистре C (0..FFH) в 2-10 код,
расположенный в регистровой паре HL. Перевод производится в соответствии с
формулой:
HL=(…((c7)×2+c6)×2+…+c1)×2+c0,
в которой ci
– разряды числа в регистре C, а удвоение и сложение с битами ci
происходит по правилам десятичной арифметики (с командой DAA после операции).
Листинг 14: подпрограмма B2D
; – – – перевод байта
(целого) в 2-10 код
; операнд C – переводимое
число, результат в HL
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 |