Перейти к содержанию
    

Проверьте

Всем привет.

 

Написал вот такой алгоритм деления. И вроде делит всё правильно и разрядность данных ее не пугает и остаток сохраняет , но чувство того , что чего-то упустил осталось.

А вот не пойму , что.

BeginDIV и ENDDIV - макросы для стека. ldwi - раскрывается в LDI. Retneg: - возврат к отрицательному числу , если делимое было отрицательное.

 

;+ Подпрограмма деления 32/16.Все результаты сохраняются в SRAM
ValueX2:
        cli
        BeginDIV
        clr    Flags
        clr    count
        clr    mean1
        clr    mean0
        clr    minut
        ldwi    Z,(StartRAM085+MulMCH); загружаем адрес значения MC
        ld    temp,Z+
        ld    temp1,Z+
        ld    mean0,Z+
        ld    mean1,Z+        ; загружаем значение MC
        lds    rab,(StartRAM085+AddMCX1H); загружаем значение делителя
        lds    rab1,(StartRAM085+AddMCX1L)
Div:        
        sub    temp1,rab1
        sbc    temp,rab
        sbc    minut,zero
        brmi    TestNEG        ; Если 0 - загружаем среднее (младший) MC
        inc    count        ; Если не 0 - прибавляем счётчик результата
        sts    (StartRAM085+TailH),minut;+               
        sts    (StartRAM085+TailMH),temp;+               
        sts    (StartRAM085+TailML),temp1;+ Здесь  остаток
        sts    (StartRAM085+TailLH),mean0;+               
        sts    (StartRAM085+TailL),mean1;+               
        rjmp    DIV        ; Снова делим
TestNEG:        
        tst    count        ; Ноль после деления?
        brne    SaveX2        ; НЕТ - сохраняем значение старшее
        sbrc    Flags,fl_Shift
        rjmp    InitShift
        ldi    count,4
        clr    minut
        ldwi    Z,(StartRAM085+MulMCH); загружаем адрес MC        
        ld    temp,Z+
        ld    temp1,Z+
        rjmp    ShiftT    
InitShift:
        ldi    count,4
        ldwi    Z,(StartRAM085+MulMCH)
        ld    minut,Z+
        ld    temp,Z+
        ld    temp1,Z+
        ld    mean0,Z+
        ld    mean1,Z+
ShiftT:            
        lsl    mean1
        rol    mean0
        rol    temp1
        rol    temp
        rol    minut
        dec    count
        brne    ShiftT
        ldwi    Z,(StartRAM085+MulMCH)
        st    Z+,minut
        st    Z+,temp
        st    Z+,temp1
        st    Z+,mean0
        st    Z+,mean1
        sbr    Flags,1<<fl_Shift        
        rjmp    Div
;************************************************
SaveX2:
        sbrc    Flags,fl_ResultH
        rjmp    RESX2M    
        sts    (StartRAM085+X2H),count; Сохраняем сотые
        sbr    Flags,1<<fl_ResultH
        rjmp    Forward
RESX2M:
        sbrc    Flags,fl_ResultM
        rjmp    RESX2L    
        sts    (StartRAM085+X2M),count; Сохраняем  десятые
        sbr    Flags,1<<fl_ResultM
        rjmp    Forward
RESX2L:
        sts    (StartRAM085+X2L),count; Сохраняем единицы
        sbr    Flags,1<<fl_ResultL
        rjmp    ValDiv
Forward:
        clr    count
        ldwi    Z,(StartRAM085+TailH)
        ld    minut,Z+
        ld    temp,Z+
        ld    temp1,Z+
        ld    mean0,Z+
        ld    mean1,Z+
        ldi    count,4
        rjmp    ShiftT
ValDiv:
        lds    rab,(StartRAM085+dtMCH)
        sbrc    rab,MsbOne
        rjmp    RetNeg
RetNeg:
        lds    temp,(StartRAM085+X2H)
        lds    temp1,(StartRAM085+X2M)
        lds    rab,(StartRAM085+X2L)
        ldi    count,4
        swap    rab
Cycle:
        lsl    rab
        rol    temp1
        dec    count
        brne    Cycle
        mov    rab1,zero
        mov    rab,zero
        sub    rab1,temp1
        sbc    rab,temp
        sub    rab1,one
        sbc    rab,zero
        sts    (StartRAM085+X2H),rab
        sts    (StartRAM085+X2M),rab1
        EndDIV
        reti

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Никто не отвечает:) Код большой слишком, долго ковырять, а пропустить что-то запросто. Я бы вам рекомендовал сделать простой тест: 100500 тыщ раз в цикле вызывать эту функцию с рандомными параметрами, и вызывать эталонную функцию с этими же параметрами. Потом сравниваете результаты, и если ошибка - смотрите что где. Не 100% гарантия, но может быть близко при хорошем генераторе.

 

Как реализовать - дело ваше: либо нативно в контроллере (используя библиотеки компилятора за эталон) - медленно, либо на компе, переписав этот код на си 1 в 1 - быстро.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересно, а почему решили писать свою реализацию? Чем не устраивала уже существующая?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересно, а почему решили писать свою реализацию? Чем не устраивала уже существующая?

Какую? От Atmel? Видел. Можно и простое вычитание до упора , тоже видел. Решил просто в "столбик" поделить. Для моей задачи быстро получается. А если вместо буфера в памяти использовать MOV , то ещё можно подсократить

И как я писал делит -то она правильно , но осталось чувство неудовлетворённости. Как будто я что-то всё таки забыл.

Например я не стал вводить запоминание тысяч , т.к. в моей задаче числа с 1xxx по идее не появятся.

но можно и дописать.

При этом я делю и 24/16 и 32/8 и 24/8 и 8/8 (c увеличением разрядности результата и могу использовать и остаток он тоже сохраняется , если нужно .

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проще и быстрее написать тест под нужные параметры. Если вас интересует безглючная работа именно у вас, при ваших условиях, - проверяйте и все увидите, забыли или нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...