SII ,я уж было очень обрадовался, увидев вторую подпрограмку деления. Но с ней, похоже что-то не то... начинаеться так: DivWord: ldi R22, 17 cp R21, R19 brcs _DWRet ... кончаеться так: _DWRet: ret
Тоесть если R21, R19 не равны, то конец всему делению Похоже самому сочинять прийдёться , методом вычитания...
Там brcs, а не brne/breq -- речь не о равенстве, а о больше/меньше (это нужно, чтобы понять, а поместится ли частное в два байта). Хотя вряд ли эта подпрограмма самая оптимальная -- писал её в спешке, причём только начав работать с АВРками, т.е. толком ещё не зная систему команд. Ну а помедитировать лениво -- работает же в реальных изделиях
Ну счас еще раз помедетировал в AVR Studio... Делимое обычно ж больше делителя... Как я понимаю R19 старшие разряды, R16 младшие разряды делимого. Хотя я для проверки всё равно в делимое 0ХFFFF загнал, а в делитель 0X5555, должно ровно 3 получиться. Пробовал и наоборот в делимое 0Х5555, в длитель 0XFFFF, так тоже, совсем не то выходит...
Судя по задаче, за которую взялся топикстартер и которая - увы - пока превышает его возможности, для апроксимации следует применять плавающую арифметику, что еще несколько сложнее. Ну поделит он 16 бит на 16 бит, получит частное и остаток. А что потом делать с этим остатком - съесть с маслом или на хлеб намазывать - XZ. Для следующей операции нужен результат предыдущей - число, а не 2 никак не связанных числа - частное и остаток. Поэтому надо сначала проанализировать задачу на алгоритмическом уровне, определиться, что сделать в целых числах, что в плавучке. А уж затем исходя из вечного противоречия - расход памяти vs быстродействие -и необходимой точности искать метод решения. У меня был печальный опыт - надо было сделать прогу для процессора, который выбрали до меня ( и без меня ) и который просто физически не способен был решить эту задачу. Пришлось извращаться - применил нестандартную 3-байтовую плавучку, размазывал вычисления по времени ( измерили точку - вычислили часть выражения - измерили 2-ю точку - продолжили вычисление выражения и т.д. ). Издели пошло в серию и выпущено несколько сотен экземпляров, но мне бы не хотелось в страшном сне увидеть тот мой код Лично мой совет - сначала заняться чем-либо попроще. Ну и читать литературу. Она иногда сеет свет.
Лично мой совет - сначала заняться чем-либо попроще. Ну и читать литературу. Она иногда сеет свет.
И обязательно разбираться с "низкоуровневыми" алгоритмами (те же операции умножения и деления "ручками", а не с помощью команд процессора), даже если используемый процессор умеет их делать сам или доступны выполняющие их чужие подпрограммы: понимание принципов никогда не помешает, а иногда может и помочь.
Полностью согласен! SII , Ваша пограмма четко и быстро работает. Ошибка у Вас только с подписанием регистров в начале... ; Параметры: ; ; R19:R16 - делимое ; R21:R20 - делитель R19 нужно исправить на R17
В операции целочисленного умножения произведение имеет удвоенную разрядность по сравнению с сомножителями, в операции деления делимое имеет вдвое большую разрядность, чем делитель, частное и остаток. Языки высокого уровня просто маскируют сей факт, но от этого он никуда не исчезает. Почитайте, например, описание команд MUL, IMUL, DIV и IDIV в современных процессорах ПК. Так и в этой подпрограмме: делимое имеет размер 4 байта и занимает 4 регистра подряд, что и отражено записью R19:R16.
Ай, шо-то Вы сильно умное для меня тут пишете. Вот ,что я сегодня на работе по бырику написал. Конечно быстродействие будет не очень , если делимое во много раз больше делителя будет... Но меня пока устраивет, а остаток, легко умножить на 10, и потом опять разделить и записать после запятой, необходимое кол-во раз
Код:
.include"tn2313def.inc" .cseg .org 0 ldi r16,RamEnd out SPL,r16 ; R17H R16L ДЕЛИМОЕ/ОСТАТОК ; R19H R18L ДЕЛИТЕЛЬ ; R21H R20L РЕЗУЛЬТАТ LDI R17,0XFF LDI R16,0XFF LDI R19,0 LDI R18,6 RCALL DEL
И обязательно разбираться с "низкоуровневыми" алгоритмами (те же операции умножения и деления "ручками", а не с помощью команд процессора)
Когда в том же проекте мне понадобилась быстрая и точная п.п SQRT ( на счету был каждый байт и каждая микросекунда) я долго мудрил на бумаге и экспериментировал в Excel`е, вспомнил из 6 класса, что (a-b)*(a+b) ~ a^2 , если b сильно меньше a, в результате получил то, что хотел. Потом мне сказали, что это алгоритм Герона, который жил еще во времена Архимеда и еще водяными насосами баловался. "Какой удар со стороны классика! " (С) О.Бендер
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения