Лови. Тока какая-то тонкость тут есть. Проверь. 31/16 делит точно. А с 32/16 не уверен. Чего-то добавить надо.
;***************************************************************************
;*
;* "div16u" - 16/16 Bit Unsigned Division
;*
;* This subroutine divides the two 16-bit numbers
;* "dd8uH:dd8uL" (dividend) and "dv16uH:dv16uL" (divisor).
;* The result is placed in "dres16uH:dres16uL" and the remainder in
;* "drem16uH:drem16uL".
;*
;* Number of words :19
;* Number of cycles :235/251 (Min/Max)
;* Low registers used :2 (drem16uL,drem16uH)
;* High registers used :5 (dres16uL/dd16uL,dres16uH/dd16uH,dv16uL,dv16uH,
;* dcnt16u)
;*
;***************************************************************************
;***** Subroutine Register Variables
.def drem16uL=r13 ;remainder
.def drem16uM=r14
.def drem16uH=r15
.def dres16uL=r9 ;result
.def dres16uM=r10
.def dres16uH=r11
.def dres16HH=r12
.def dd16uL =r9 ;divident
.def dd16uM =r10
.def dd16uH =r11
.def dd16uHH =r12
.def dv16uL =r19 ;divisor
.def dv16uH =r20
.def dcnt16u =r21
.def zero_reg=r22
;***** Code
div16u: clr drem16uL ;clear remainder Low byte
sub drem16uM,drem16uM;clear remainder High byte and carry
sub drem16uH,drem16uH;clear remainder High byte and carry
ldi dcnt16u,33 ;init loop counter
d16u_1: rol dd16uL ;shift left dividend
rol dd16uM
rol dd16uH
rol dd16uHH
dec dcnt16u ;decrement counter
brne d16u_2 ;if done
ret ; return
d16u_2: rol drem16uL ;shift dividend into remainder
rol drem16uM
rol drem16uH
sub drem16uL,dv16uL ;remainder = remainder - divisor
sbc drem16uM,dv16uH ;
sbc drem16uH,zero_reg
brcc d16u_3 ;if result negative
add drem16uL,dv16uL ; restore remainder
adc drem16uM,dv16uH
adc drem16uH,zero_reg
clc ; clear carry to be shifted into result
rjmp d16u_1 ;else
d16u_3: sec ; set carry to be shifted into result
rjmp d16u_1