Все это легко перепихивается и на другие платформа. В данный момент пишу под PICи, а в АРМ влазить нет времени.

Еще пару десятков тактов в среднем можно сэкономить, если развернуть цикл в ущерб объему (для тех, кому важна скорость):
CODE
_Sqrt16:
SUB W0, #0x0000, W2; Сравнение аргумента с '0' + техническое перемещение.
BRA GTU, .+4 ; Если аргумент больше - переход к алгоритму извлечения корня, иначе:
RETURN ; выход с аргументом в качестве результата.
FF1L W0, W0 ; Определение номера старшего разряда.
DEC W0, W0 ; Технический декремент номера разряда.
LSR W0, W0 ; Разбиение разрядов числа на пары.
MUL.UU W0, #7, W0; Вычисление длины прыжка с обнулением регистра результата W1.
BRA W0 ; Переход к итерации с необходимым номером.
; Итерация 1
MOV #0x4000, W0 ; k = 0x4000.
BRA .+4 ; Сокращение одного машинного такта.
NOP ; Техническое заполнение тела итерации.
CP W0, W2 ;
BRA GTU, .+6 ; if(x >= tmp) {
SUB W2, W0, W2; x -= tmp;
IOR W1, W0, W1; res |= k; }
; Итерация 2
MOV #0x1000, W0 ;
IOR W0, W1, W3; tmp = k | res
LSR W1, W1 ; res >>= 1;
CP W3, W2 ;
BRA GTU, .+6 ; if(x >= tmp) {
SUB W2, W3, W2; x -= tmp;
IOR W1, W0, W1; res |= k; }
; Итерация 3
MOV #0x0400, W0 ;
IOR W0, W1, W3; tmp = k | res
LSR W1, W1 ; res >>= 1;
CP W3, W2 ;
BRA GTU, .+6 ; if(x >= tmp) {
SUB W2, W3, W2; x -= tmp;
IOR W1, W0, W1; res |= k; }
; Итерация 4
MOV #0x0100, W0 ;
IOR W0, W1, W3; tmp = k | res
LSR W1, W1 ; res >>= 1;
CP W3, W2 ;
BRA GTU, .+6 ; if(x >= tmp) {
SUB W2, W3, W2; x -= tmp;
IOR W1, W0, W1; res |= k; }
; Итерация 5
MOV #0x0040, W0 ;
IOR W0, W1, W3; tmp = k | res
LSR W1, W1 ; res >>= 1;
CP W3, W2 ;
BRA GTU, .+6 ; if(x >= tmp) {
SUB W2, W3, W2; x -= tmp;
IOR W1, W0, W1; res |= k; }
; Итерация 6
MOV #0x0010, W0 ;
IOR W0, W1, W3; tmp = k | res
LSR W1, W1 ; res >>= 1;
CP W3, W2 ;
BRA GTU, .+6 ; if(x >= tmp) {
SUB W2, W3, W2; x -= tmp;
IOR W1, W0, W1; res |= k; }
; Итерация 7
MOV #0x0004, W0 ;
IOR W0, W1, W3; tmp = k | res
LSR W1, W1 ; res >>= 1;
CP W3, W2 ;
BRA GTU, .+6 ; if(x >= tmp) {
SUB W2, W3, W2; x -= tmp;
IOR W1, W0, W1; res |= k; }
; Итерация 8
IOR W1, #0x0001, W3; tmp = k | res
LSR W1, W0 ; res >>= 1;
CP W3, W2 ;
BRA GTU, .+6 ; if(x >= tmp) {
SUB W2, W3, W2; x -= tmp;
IOR W0, #0x0001, W0; res |= k; }
; Округление до ближайшего целого
CP W2, W0 ; Сравнение результата с остатком.
BRA LEU, .+4 ; Если остаток меньше, либо равен - пропуск инструкции, иначе:
INC W0, W0 ; инкремент результата.
RETURN ; Выход из процедуры.
Сообщение отредактировал IgorKossak - Sep 22 2012, 16:42
Причина редактирования: [codebox] для длинного кода!!!!!!!