ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
17 мая
37305 Топик полностью
mse (15.08.2005 12:13, просмотров: 1) ответил Aleksey75 на Help!!! Будьте добры бросте исходники 32 битного деления на асме для AVR (atmega8)...........Заранее благодарен
Лови. Тока какая-то тонкость тут есть. Проверь. 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