Цитата(777777 @ Jul 14 2008, 14:36)

А числа целые или с плавающей точкой? Если с плавающей, то написать на Си, а если целые (или с фиксированной точкой), то искать "алгорим Ньютона" для извлечения корня.
У AVR нет аппаратного деления. Оно реализовано через вычитания и сдвиги. И корень можно вычислять через вычитания и сдвиги.
Только при этом для деления число проходов цикла равно числу разрядов числа, а для корня - в два раза меньше. Правда, там ещё другие расходы есть (дополнительные операции ИЛИ, ещё один сдвиг), да и сдвиг на два у AVR реализуется как два сдвига на 1, итого вычисление корня по времени будет не в два раза быстрее программного деления, а близко к нему.
А "по Ньютону" нужно будет несколько делений, что будет в несколько раз дольше.
Обратите внимание на обсуждение по первой приведенной мной ссылке - там корень через вычитания/сдвиги оказался не медленнее "Ньютона" даже на 80386, который имеет аппаратное деление (впрочем, не слишком быстрое, но всё равно быстрее, чем программное через вычитания и сдвиги).
p.s. Александр Труш когда-то публиковал корень именно для AVR именно на асме. И где-то его недавно цитировали. Надо поискать.
Нашёл в своих завалах.
Ага, ещё и 24-битный аргумент. Видать, ему надо было именно столько (например, сумма не слишком болшьшого количества квадратов 10-битных отсчётов АЦП - 16 дико мало, 32 дико много).
Код
;*******************************************************************************
*********************
;*
;* Подпрограмма вычисления квадратного корня для 24-ти битного аргумента *
;* (c) 1998 Alexander Trush http://trush.da.ru trush@ropnet.ru 2:5020/392.40
;*
; Вы можете свободно использовать, распространять, модифицировать этот
; код до тех пор, пока вы указываете моё авторство и распространяете
; это требование. Кроме того, я хотел бы получать уведомление о
; применении этого кода по e-mail (trush@kbotd.ru).
sqrt24: ldi mask,1; Используем маску в регистре, т.к. команды EORI нет...
ldi count,12; Последний бит значения корня не требует специального
; подхода - есть запас от потери битов аж 4 бита
clr16 work_h, work_l
clr16 dist_h, dist_l; Очистка накопителя значения корня
sqrt24_1: cpi src_h, 64
cpc work_l, dist_l
cpc work_h, dist_h
brcs sqrt24_2
subi src_h, 64
sbc work_l, dist_l
sbc work_h, dist_h
sqrt24_2: rol dist_l
rol dist_h
eor dist_l, mask; Инверсия младшего бита значания корня,
; т.к. при заёме должны писать 0, и 1 при отсутствии
lsl src_l; Сдвиг аргумента на 2 бита
rol src_m; work_h:work_l:src_h:src_m:src_l <<= 2
rol src_h
rol work_l
rol work_h
lsl src_l
rol src_m
rol src_h
rol work_l
rol work_h
dec count; Получили ли все биты значения корня кроме последнего?..
brne sqrt24_1
cp dist_l, work_l
cpc dist_h, work_h
adc dist_l, src_m; Команды ADCI нет, а src_m точно здесь равен 0
adc dist_h, src_m
ret
;******************************************************************************