Алгоритм управления задан следующим уравнением:
В данном уравнении . Поскольку разрядность регистров не позволяет использовать такие большие коэффициенты, разделим коэффициенты a0, a1, a2 на значение коэффициента a0=15625. В результате получим:
В алгоритме управления используются операции сложения, вычитания чисел со знаком и умножение на вещественные коэффициенты a0, a1 и a2. Для реализации вычитания следует использовать операцию сложения чисел с использованием дополнительного кода, а затем результат переводить в прямой код. Умножение целого числа со знаком на вещественное можно реализуем следующим образом:
1. Беззнаковое умножение модуля числа на целую часть коэффициента.
2. Беззнаковое умножение числа на дробную часть коэффициента.
3. Восстановление знаков результатов умножения.
4. Сложение результатов с использованием дополнительного кода.
Схема алгоритма основной программы (начало)
Схема алгоритма основной программы (конец)
Схема алгоритма умножения целых чисел
Схема алгоритма сложения чисел со знаком
Схема алгоритма перевода чисел из прямого кода в дополнительный код
Схема алгоритма перевода чисел из дополнительного кода в прямой код
Схема умножения целого числа на дробное число
Текст программы
;********************************************управляющие команды
LXI H, 13h
DAD SP
MOV A, L
ANI 11111110b
MOV L, A
SPHL
CALL stackdef
CALL prog ;Здесь происходит вызов программы
HLT
DW 0
DB 0
;******************************************НАЧАЛО РАБОТЫ ПРОГРАММЫ
prog: JMP LOAD
;******************************************инициализация
LOAD: MVI A, 1H ;загрузка в регистр А целой части коэфф. а0
STA 11H ;пересылка в память
MVI A, 10H ;загрузка в регистр А дробной части коэфф. а0
STA 10H ;загрузка в память
;******************************************инициализация
MVI A, 2H ;загрузка в регистр А целой части коэфф. а1
STA 13H ;пересылка в память
MVI A, 10H ;загрузка в регистр А целой части коэфф. а1
STA 12H ;пересылка в память
;******************************************инициализация
MVI A, 1H ;загрузка в регистр А целой части коэфф. а1
STA 15H ;пересылка в память
MVI A, 0H ;загрузка в регистр А целой части коэфф. а1
STA 14H ;пересылка в память
;******************************************инициализация
MVI A, 1H ;загрузка в регистр А Xn *здесь изменяем
STA 16H ;пересылка в память *значения входного
MVI A, 81H ;загрузка в регистр А X(n-1)*воздействия
STA 17H ;пересылка в память *
MVI A, 1H ;загрузка в регистр А X(n-2)*
STA 18H ;пересылка в память
;******************************************умножение целой части а0 на Xn
LDA 11H ;загрузка в рег. А целой части коэф. а0
MOV B,A ;пересылка а0 в регистры B, C, H
MOV C,A
MOV H,A
LDA 16H ;загрузка в рег. А множимого (Xn)
CALL UMN ;вызов подпрограммы умножения
STA 1DH ;запись результата умножения в память
;******************************************умножение дробной части а0 на Xn
LDA 10H ;загрузка в рег. А дробной части коэф. а0
MOV B,A ;пересылка а0 в регистры B, C, H
MOV C,A
MOV H,A
LDA 16H ;загрузка в рег. А множимого (Xn)
CALL UMN ;вызов подпрограммы умножения
STA 1CH ;запись результата умножения в память
;******************************************умножение целой части а1 на X(n-1)
LDA 13H ;загрузка в рег. А целой части коэф. а1
MOV B,A ;пересылка а0 в регистры B, C, H
MOV C,A
MOV H,A
LDA 17H ;загрузка в рег. А множимого (X(n-1))
CALL UMN ;вызов подпрограммы умножения
STA 1FH ;запись результата умножения в память
;******************************************умножение дробной части а1 на X(n-1)
LDA 12H ;загрузка в рег. А дробной части коэф. а1
MOV B,A ;пересылка а0 в регистры B, C, H
MOV C,A
MOV H,A
LDA 17H ;загрузка в рег. А множимого (X(n-1))
CALL UMN ;вызов подпрограммы умножения
RAL ;правый циклический сдвиг через флаг переноса (для учета знака "-"
;перед коэфф. а1 получается число типа 81h)
CMC ;инвертирование флага переноса
RRC ;циклический сдвиг вправо
STA 1EH ;сохранение результата
;******************************************умножение целой части а2 на X(n-2)
LDA 15H ;загрузка в рег. А дробной части коэф. а2
MOV B,A ;пересылка а0 в регистры B, C, H
MOV C,A
MOV H,A
LDA 18H ;загрузка в рег. А множимого (X(n-2))
CALL UMN ;вызов подпрограммы умножения
STA 21H ;запись результата умножения в память
;******************************************умножение дробной части а2 на X(n-2)
LDA 14H ;загрузка в рег. А дробной части коэф. а2
MOV B,A ;пересылка а0 в регистры B, C, H
MOV C,A
MOV H,A
LDA 18H ;загрузка в рег. А множимого (X(n-2))
CALL UMN ;вызов подпрограммы умножения
STA 20H ;запись результата умножения в память
HLT ;останов программы для контроля значений
;******************************************проверка знака слагаемых а0*Xn
LDA 1CH ;загрузка в рег. А дробной части а0*Xn
MOV C,A ;пересылка в регистр
LDA 1DH ;загрузка в рег. А целой части а0*Xn
MOV B,A ;пересылка в регистр
RAL ;правый циклический сдвиг через флаг переноса
CC DK ;условный переход к подпрограмме перевода
;в дополнительный код, при С=1
RRC ;циклический сдвиг вправо
STA 1DH ;сохранение целой части в память
MOV A,C ;пересылка в А
STA 1CH ;сохранение дробной части в памяти
;******************************************проверка знака слагаемых а1*X(n-1)
LDA 1EH ;загрузка в рег. А дробной части а1*X(n-1)
MOV C,A ;пересылка в регистр
LDA 1FH ;загрузка в рег. А целой части а1*X(n-1)
MOV B,A ;пересылка в регистр
RAL ;правый циклический сдвиг через флаг переноса
CC DK ;условный переход к подпрограмме перевода
;в дополнительный код, при С=1
STA 1FH ;сохранение целой части в память
MOV A,B ;пересылка в А
STA 1EH ;сохранение дробной части в памяти
;******************************************проверка знака слагаемых а2*X(n-2)
LDA 20H ;загрузка в рег. А дробной части а2*X(n-2)
MOV C,A ;пересылка в регистр
LDA 21H ;загрузка в рег. А целой части а2*X(n-2)
MOV B,A ;пересылка в регистр
RAL ;правый циклический сдвиг через флаг переноса
CC DK ;условный переход к подпрограмме перевода
;в дополнительный код, при С=1
RRC ;циклический сдвиг вправо
STA 21H ;сохранение целой части в память
MOV A,C ;пересылка в А
STA 20H ;сохранение дробной части в памяти
HLT ;останов программы для контроля значений
;******************************************сложение а0*Xn+а1*X(n-1)
LDA 1CH ;загрузка в рег. А дробной части а0*Xn
MOV B,A ;пересылка в регистр
LDA 1FH ;загрузка в рег. А дробной части а1*X(n-1)
ADD B ;сложение дробных частей
JNC METKA9 ;если нет переноса единицы из младшего
;в старший байт, то перейти по метке
STA 22H ;запись результата в память
LDA 1DH ;загрузка в рег. А целой части а0*Xn
MOV B,A ;пересылка в регистр
LDA 1EH ;загрузка в рег. А целой части а1*X(n-1)
ADD B ;сложение целых частей
INR A ;учет единицы переноса (прибавляем к целой части 1)
STA 23H ;запись результата в память
JMP METKA10 ;безусловный переход пометке
METKA9: STA 22H ;запись результата в память
LDA 1DH ;загрузка в рег. А целой части а0*Xn
MOV B,A ;пересылка в регистр
LDA 1EH ;загрузка в рег. А целой части а1*X(n-1)
ADD B ;сложение целых частей
STA 23H ;запись результата в память
;******************************************проверка знака результата а0*Xn+а1*X(n-1)
METKA10:HLT ;останов программы для контроля значений
LDA 22H ;загрузка в рег. А дробной части а0*Xn+а1*X(n-1)
MOV C,A ;пересылка в регистр
LDA 23H ;загрузка в рег. А целой части а0*Xn+а1*X(n-1)
MOV B,A ;пересылка в регистр
RAL ;правый циклический сдвиг через флаг переноса
CC PK ;условный переход к подпрограмме перевода
;в прямой код, при С=1
MOV A,B ;пересылка в регистр
STA 23H ;запись результата в память
MOV A,C ;пересылка в регистр
STA 22H ;запись результата в память
HLT ;останов программы для контроля значений
;******************************************проверка знака слагаемых а0*Xn+а1*X(n-1)
LDA 22H ;загрузка в рег. А дробной части а0*Xn+а1*X(n-1)
MOV C,A ;пересылка в регистр
LDA 23H ;загрузка в рег. А целой части а0*Xn+а1*X(n-1)
MOV B,A ;пересылка в регистр
RAL ;правый циклический сдвиг через флаг переноса
CC DK ;условный переход к подпрограмме перевода
;в дополнительный код, при С=1
STA 22H ;запись результата в память
MOV A,B ;пересылка в регистр
STA 23H ;запись результата в память
;******************************************сложение (а0*Xn+а1*X(n-1))+а2*X(n-2)
LDA 20H ;загрузка в рег. А дробной части а2*X(n-2)
MOV B,A ;пересылка в регистр
LDA 22H ;загрузка в рег. А дробной части (а0*Xn+а1*X(n-1))
ADD B ;сложение дробных частей
JNC METKA11 ;если нет переноса единицы из младшего
;в старший байт, то перейти по метке
STA 22H ;запись результата в память
LDA 21H ;загрузка в рег. А целой части а2*X(n-2)
MOV B,A ;пересылка в регистр
LDA 23H ;загрузка в рег. А целой части (а0*Xn+а1*X(n-1))
ADD B ;сложение целых частей
INR A ;учет единицы переноса (прибавляем к целой части 1)
STA 23H ;запись результата в память
JMP METKA12 ;безусловный переход пометке
METKA11:STA 22H ;запись результата в память
LDA 21H ;загрузка в рег. А целой части а2*X(n-2)
MOV B,A ;пересылка в регистр
LDA 23H ;загрузка в рег. А целой части (а0*Xn+а1*X(n-1))
ADD B ;сложение целых частей
STA 23H ;запись результата в память
;******************************************проверка знака результата (а0*Xn+а1*X(n-1))+а2*X(n-2)
METKA12:HLT ;останов программы для контроля значений
LDA 22H ;загрузка в рег. А дробной части (а0*Xn+а1*X(n-1))+а2*X(n-2)
MOV C,A ;пересылка в регистр
LDA 23H ;загрузка в рег. А целой части (а0*Xn+а1*X(n-1))+а2*X(n-2)
MOV B,A ;пересылка в регистр
RAL ;правый циклический сдвиг через флаг переноса
CC PK ;условный переход к подпрограмме перевода
;в прямой код, при С=1
MOV A,B ;пересылка в регистр
STA 22H ;запись результата в память
MOV A,C ;пересылка в регистр
STA 23H ;запись результата в память
;******************************************
HLT
;******************************************
;******************************************подпрограмма перевода числа из дополнительного кода в прямой
PK: MOV A,C ;пересылка в регистр
DCR A ;декремент дробной части
JNC METKA14 ;условный переход по метке если C<>0
DCR B ;учет заема из дробной части
METKA14:XRI 0FFH ;инверсия дробной части
MOV C,A ;пересылка в регистр
MOV A,B ;пересылка в регистр
XRI 0FFH ;инверсия целой части
RLC ;циклический сдвиг влево
STC ;установка флага переноса С=1. для восстановления знака в числе
RAR ;правый циклический сдвиг через флаг переноса
MOV B,A ;пересылка в регистр
RET ;выход из подпрограммы
;******************************************подпрограмма перевода числа из прямого в дополнительный
DK: MOV A,B ;пересылка в регистр
XRI 0FFH ;инверсия целой части
RLC ;восстановление знака числа
STC
RAR
MOV B,A ;пересылка в регистр
MOV A,C ;пересылка в регистр
XRI 0FFH ;инверсия дробной части
ADI 1H ;инкремент дробной части
JNC METKA8 ;если нет есть переполнение, то переход по метке
INR B ;учет переноса из дробной части в случае переполнения
METKA8: MOV C,A ;пересылка в регистр
RET ;выход из подпрограммы
;******************************************подпрограмма умножения двух чисел
UMN: MOV E,A ;пересылка в регистр
RAL
RRC
MOV D,A ;пересылка в регистр
MOV A,C ;пересылка в регистр
JMP METKA3 ;безусловный переход по метке
METKA2: MOV A,C
METKA3: ADD B
MOV B,A
MOV A,D
SUI 1H
MOV D, A
JM METKA7
JNZ METKA2
MOV A,B
SUB C
MOV B,A
MOV A,E
RAL
JNC METKA5
MOV A,B
RLC
STC
RAR
JMP METKA6
METKA5: MOV A,B
METKA6: RET
METKA7: MVI A,0H
RET
RET
;********************************************управляющие команды
stacksize DW 50h
stackdef: POP B
CALL stackbeg
LXI H, 1Ch
DAD D
MOV D, H
MOV E, L
LHLD stacksize
INX H
MOV A, L
RAL
MOV L, A
MOV A, H
RAL
MOV H, A
DAD D
MOV A, L
ANI 11111110b
MOV L, A
SPHL
PUSH B
RET
stackbeg: POP D
PUSH D
RET
Литература
1. Бесекерский В.А., Попов Е.П., Теория систем автоматического регулирования. М.: Наука, 1975. 767 с.
2. Гуртовцев А.Л., Гудыменко С.В. Программы для микропроцессоров: Справ. пособие. Мн.: Выш. шк., 1989. 352 с.
3. Микропроцессорные системы автоматического управления. Под ред. В.А. Бесекерского. – Л.: Машиностроение, 1965 с. |