Здравствуйте, Игорь!
Вот Вам программа для процессора КР1878ВЕ1
Программа является переводом программы из приведенной Вами ссылки с языка ассемблера AVR на язык КР1878ВЕ1.
Формат вещественного числа уменьшен с 4-х байт до 3-х, за счет усечения младших бит мантиссы.
Для решения поставленной задачи этого вполне достаточно.
Будут вопросы, спрашивайте в мини-форуме...
[code h=200];дадим для удобства имена используемых регистров
#define pA %a0 ;первый байт первого числа - порядок
#define mAH %a1 ;второй байт первого числа - старший байт мантиссы
#define mAL %a2 ;третий байт первого числа - младший байт мантиссы
#define pB %b0 ;первый байт второго числа - порядок
#define mBH %b1 ;второй байт второго числа - старший байт мантиссы
#define mBL %b2 ;третий байт второго числа - младший байт мантиссы
#define acc %c0 ;рабочий регистр - аккумулятор
#define sign %c1 ;регистр для хранения знака числа (вместе с порядком)
jmp Start ;<0> Начальный пуск
jmp Err ;<1> Сторожевой таймер
jmp Err ;<2> Сбой программы (стеки,память)
jmp Err ;<3> Таймер A
jmp Err ;<4>
jmp Err ;<5>
jmp Err ;<6> Порт A
jmp Err ;<7>
jmp Err ;<8>
jmp Err ;<9>
jmp Err ;<10>
jmp Err ;<11>
jmp Err ;<12>
jmp Err ;<13>
jmp Err ;<14>
jmp Err ;<15>
Err: jmp Err ;все ошибки приведут сюда
Start: ;старт программы
cst 8 ;запрещаем прерывания (IE=0)
ldr #a,40h ;Установка сегмента A
ldr #b,48h ;Установка сегмента B
ldr #c,50h ;Установка сегмента C
;первое число = 5.75 = 0.1000000|1.0111000|00000000
movl pA,40h ;знак + 7 старших бит порядка
movl mAH,0b8h ;мл бит порядка + 7 старших бит мантиссы
movl mAL,00h ;8 младших бит мантиссы
;второе число = 2.25 = 0.1000000|0.0010000|00000000
movl pB,40h ;знак + 7 старших бит порядка
movl mBH,10h ;мл бит порядка + 7 старших бит мантиссы
movl mBL,00h ;8 младших бит мантиссы
jsr AddF ;складываем
Exit: jmp Exit ;все решено, крутимся на месте.
;функция сложения двух вещественных чисел
AddF:
;проверим на совпадение знаков чисел
;нас интересует только старший бит - бит знака
mov acc, pA ;acc = pA
xor acc, pB ;acc = pA xor pB
btth acc, 1000b ;проверим старший бит результата
jeq AddF1 ;0, когда знаки одинаковые - идем дальше
;иначе
bish pB, 1000b ;меняем знак у В
jmp SubF ;и идем на вычитание! (A+(-B)=A-(+B))
AddF1: jsr cp_B_0 ;сравним В с 0
jeq Return ;результат в А
jsr cp_A_0 ;сравнение A с 0
jne AddF2 ;оба не 0 - идем дальше
;А=0, значит результатом будет В
jsr swapAB ;обмен A и В
rts ;результат в А
AddF2: mov sign, pB ;сохранение знака вместе с порядком рВ.7
;приведем числа к удобному для использования виду:
;порядок теряем (он сохранен и будет учтен позже),
;порядок полностью в байте порядка.
;в старшем байте мантиссы добавляем подразумеваемую старшую единицу
jsr rec ;восстановление первого числа в А
jsr swapAB ;теперь А=В, а В=А
jsr rec ;восстановление второго числа в А
;смотрим, какое из чисел больше, для этого сравниваем порядки чисел
mov acc, pA ;вычитание порядков acc = pА - pB
sub acc, pB
jns AddF3 ;переход, если больше 0 (второе(в А) больше первого(в В)),
jsr swapAB ; иначе обмен и
mov acc, pA ; снова вычитание acc = pA - pB
sub acc, pB
AddF3:
;меньшее число в В, большее - в А
;в acc имеем разность порядков чисел, Z=1, если 0, т.е. порядки равны
jeq AddF6 ;переход, если порядки равны
;определим, есть ли потеря значимости,
;т.е. насколько одно число больше второго.
;если больше чем на 15, то меньшее число при сдвиге просто обнулится
;и результат будет равен большему числу
cmpl acc, 16 ;сравниваем
jc AddF4 ;есть, что складывать
jmp AddF7 ;переход при потере значимости
AddF4: mov pA, acc ;разность порядков в рА
jsr swapAB ;разность теперь в рВ, мантисса большего числа в mB
;выравним порядки чисел, для этого сдвинем меньшее число (в А) на число бит,
;равное разности порядков
AddF5: jsr shift ;сдвиг в регистрах mА
inc pA ;увеличиваем порядок меньшего числа
dec pB ;уменьшаем разность порядков
jne AddF5
;порядки выравнены
AddF6: add mAL, mBL ;сладываем мл байты мантисс
adc mAH ;учтем перенос
add mAH, mBH ;ст байты мантисс
;проверим, надо ли число нормализовать, т.к. у числа должна быть целая часть, равная 1
;исходное число с единицей в старшем разряде
;если не будет переноса в бит С, то число осталось нормализованным
jnc AddF7 ;проверка нарушения нормализации
;есть нарушение, правим
inc pA ;корректируем порядок
;есть опасность переполнения, когда порядок изменится с ffh на 00h,
;проверим
stc ;взведем на всякий случай флаг ошибки
jeq Return ;выход с флагом переполнения С
jsr shift ;корректируем мантиссу сдвигом вправо
AddF7: jsr pack ;форматирование результата
Return: rts ;выход
;------------------------------------------------------
;вычитание А-В
SubF: mov acc, pA ;сравнение знаков чисел
xor acc, pB
btth acc, 1000b ;проверим старший бит результата
jeq SubF1 ;0, когда знаки одинаковые - идем дальше
;иначе
bish pB, 1000b ;изменение знака
jmp AddF ;считаем сумму A-(-B)=A+B
SubF1: jsr cp_B_0 ;проверка В на 0
jeq Return ;результат равен А
jsr cp_A_0 ;проверка A на 0
jne SubF2 ;оба не 0, идем дальше
jsr swapAB ;обмен операндов
bish pA, 1000b ; со сменой знака результата
rts ;результат A=-B
SubF2: mov sign, pA ;сохраняем знак
jsr rec ;восстановление числа А
jsr swapAB ;теперь в рА порядок 2-го числа
jsr rec ;восстановление числа В в регистрах А
;определим, какое число больше
mov acc, pB ;из порядка 1-го вычитаем
sub acc, pA ; порядок 2-го
jne SubF3 ;числа разные
cmp mBH, mAH ;при равенстве порядков
jne SubF3 ; сравниваем мантиссы
cmp mBL, mAL
jne SubF3
clr pA ;если числа равны,
clr mAH ; результат равен 0
clr mAL
rts
SubF3: jnc SubF4 ;переход, если 1-е число
; (оно в pB,mB) больше,
jsr swapAB ; иначе обмен числами
btgh sign, 1000b ; и изменение знака в sign
SubF4: mov acc, pB ;снова вычитание порядков
sub acc, pA
jeq SubF7 ;переход при одинаковых порядках
cmpl acc, 16 ;проверим на потерю значимости
jc SubF6 ;идем дальше
jsr swapAB ;передача большего числа
; в (pA,mA) перед
jmp SubF9 ; форматированием результата
SubF6: jsr shift ;сдвиг мантиссы меньшего числа
dec acc ; в mА, пока
jne SubF6 ; разность порядков не равна 0
;Вычитание мантисс и сохранение разности в mА
SubF7: sub mBL, mAL ;мл б мантиссы
mov mAL, mBL
sbc mBH ;учитываем заем
sub mBH, mAH ;ст б мантиссы
mov mAH, mBH
mov pA, pB ;передача порядка результата в pA
SubF8: btth mAH, 1000b ;проверка нарушения нормализации
jnz SubF9 ;переход, если нарушения нет,
dec pA ; иначе, не сдвигая мантиссу,
jc SubQuit ;при антипереполнении выходим
; с флагом C=1, иначе
shl mAL ; сдвигаем мантиссу mА влево
rlc mAH
cst 1 ; и сбрасываем флаг C
jmp SubF8 ;повторяем проверку
SubF9: jsr pack ;форматируем результат
SubQuit:rts ;выход из процедуры вычитания
;-------------------------------------------
;вспомогательные подпрограммы
;-------------------------------------------
;Восстановление операнда из базового формата
rec: shl mAH ;младший разряд порядка (ст бит байта) в С
rlc pA ;восстановление порядка
shr mAH ;сдвиг вправо мантиссы
bish mAH, 1000b ;восстановление скрытой 1
rts
;Упаковка в базовый формат
pack: clr pB ;здесь сформируем байт с младшим битом
; порядка на старшем месте
shl sign ;ст бит (знак) уходит в С
rrc pA ;вводим знак в рА.7, мл бит в С
rrc pB ;вводим мл бит порядка на место ст бита pB
bich mAH, 1000b ;сначала обнулим старший бит ст байта мантиссы
or mAH, pB ;пишем его на свое место
rts
;Обмен операндов
swapAB: xor pA, pB ;обмен регистров
xor pB, pA ; рА и рВ
xor pA, pB ; за три операции
xor mAL, mBL
xor mBL, mAL
xor mAL, mBL
xor mAH, mBH
xor mBH, mAH
xor mAH, mBH
rts
;сравнение А(В) с 0
cp_A_0: mov acc, pA
or acc, mAH
or acc, mAL ;при A=0 возвращает флаг Z=1
rts ;при A!=0 – Z=0
cp_B_0: mov acc, pB
or acc, mBH
or acc, mBL ;при B=0 возвращает флаг Z=1
rts ;при B!=0 – Z=0
;Сдвиг вправо 24-разрядной мантиссы mA
shift: shr mAH
rrc mAL
clc
rts
.END [/code]
Вот здесь подправленный код из приведенной Вами ссылки для AVR:
avr.rar (3.1 кб)