⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 math.asm

📁 Library for the 8051 microcontroller. such as math routine, hexBCD, LCD, Keyboard, I2C, Remote, Ke
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;
; output:   r1, r0 = quotient Q of division Q = X / Y
;           r3, r2 = remainder 
;
; alters:   acc, B, dpl, dph, r4, r5, r6, r7, flags
;====================================================================

UDIV16:        mov     r7, #0          ; clear partial remainder
               mov     r6, #0
               mov     B, #16          ; set loop count

div_loop:      clr     C               ; clear carry flag
               mov     a, r0           ; shift the highest bit of
               rlc     a               ; the dividend into...
               mov     r0, a
               mov     a, r1
               rlc     a
               mov     r1, a
               mov     a, r6           ; ... the lowest bit of the
               rlc     a               ; partial remainder
               mov     r6, a
               mov     a, r7
               rlc     a
               mov     r7, a
               mov     a, r6           ; trial subtract divisor
               clr     C               ; from partial remainder
               subb    a, r2
               mov     dpl, a
               mov     a, r7
               subb    a, r3
               mov     dph, a
               cpl     C               ; complement external borrow
               jnc     div_1           ; update partial remainder if
                                       ; borrow
               mov     r7, dph         ; update partial remainder
               mov     r6, dpl
div_1:         mov     a, r4           ; shift result bit into partial
               rlc     a               ; quotient
               mov     r4, a
               mov     a, r5
               rlc     a
               mov     r5, a
               djnz    B, div_loop
               mov     a, r5           ; put quotient in r0, and r1
               mov     r1, a
               mov     a, r4
               mov     r0, a
               mov     a, r7           ; get remainder, saved before the
               mov     r3, a           ; last subtraction
               mov     a, r6
               mov     r2, a
               ret


;====================================================================
; subroutine DIV32
; 32-Bit / 16-Bit to 32-Bit Quotient & remainder signed Divide
; 2's Complement Format
;
; input:    r3, r2, r1, r0 = Dividend X
;           r5, r4 = Divisor Y
;
; output:   r3, r2, r1, r0 = quotient Q of division Q = X / Y
;           r7, r6, r5, r4 = remainder
;           Carry C is set if Y = 0, i.e. divide by 0 attempted
;
; calls:    UDIV32, Cr0r3, Cr4r5, Mr0r3
;
; alters:   acc, flags, Bits 21H & 22H
;====================================================================

DIV32:         anl     PSW, #0E7H      ; Register Bank 0
               mov     a, r4           ; get divisor high byte
               orl     a, r5           ; OR with low byte
               jnz     div32_OK        ; divisor OK if not 0
               setb    C               ; else, overflow
               ret

div32_OK:      acall   Cr0r3           ; 2's comp -> Mag/Sign
               acall   Cr4r5           ; 2's comp -> Mag/Sign
               acall   UDIV32
               acall   Mr0r3           ; Mag/Sign -> 2's Comp
               clr     C               ; divisor is not 0
               ret                     ; done


;====================================================================
; subroutine UDIV32
; 32-Bit / 16-Bit to 32-Bit Quotient & Remainder Unsigned Divide
;
; input:    r3, r2, r1, r0 = Dividend X
;           r5, r4 = Divisor Y
;
; output:   r3, r2, r1, r0 = quotient Q of division Q = X / Y
;           r7, r6, r5, r4 = remainder
;;
; alters:   acc, flags
;====================================================================

UDIV32:        push    08              ; Save Register Bank 1
               push    09
               push    0AH
               push    0BH
               push    0CH
               push    0DH
               push    0EH
               push    0FH
               push    dpl
               push    dph
               push    B
               setb    RS0             ; Select Register Bank 1
               mov     r7, #0          ; clear partial remainder
               mov     r6, #0
               mov     r5, #0          
               mov     r4, #0
               mov     B, #32          ; set loop count

div_lp32:      clr     RS0             ; Select Register Bank 0
               clr     C               ; clear carry flag
               mov     a, r0           ; shift the highest bit of the
               rlc     a               ; dividend into...
               mov     r0, a
               mov     a, r1
               rlc     a
               mov     r1, a
               mov     a, r2
               rlc     a
               mov     r2, a
               mov     a, r3
               rlc     a
               mov     r3, a
               setb    RS0             ; Select Register Bank 1
               mov     a, r4           ; ... the lowest bit of the
               rlc     a               ; partial remainder
               mov     r4, a
               mov     a, r5
               rlc     a
               mov     r5, a
               mov     a, r6
               rlc     a
               mov     r6, a
               mov     a, r7
               rlc     a
               mov     r7, a
               mov     a, r4           ; trial subtract divisor from
               clr     C               ; partial remainder
               subb    a, 04
               mov     dpl, a
               mov     a, r5
               subb    a, 05
               mov     dph, a
               mov     a, r6
               subb    a, #0
               mov     06, a
               mov     a, r7
               subb    a, #0
               mov     07, a
               cpl     C               ; complement external borrow
               jnc     div_321         ; update partial remainder if
                                       ; borrow
               mov     r7, 07          ; update partial remainder
               mov     r6, 06
               mov     r5, dph
               mov     r4, dpl
div_321:       mov     a, r0           ; shift result bit into partial
               rlc     a               ; quotient
               mov     r0, a
               mov     a, r1
               rlc     a
               mov     r1, a
               mov     a, r2
               rlc     a
               mov     r2, a
               mov     a, r3
               rlc     a
               mov     r3, a
               djnz    B, div_lp32

               mov     07, r7          ; put remainder, saved before the
               mov     06, r6          ; last subtraction, in bank 0
               mov     05, r5
               mov     04, r4
               mov     03, r3          ; put quotient in bank 0
               mov     02, r2
               mov     01, r1
               mov     00, r0
               clr     RS0
               pop     B
               pop     dph
               pop     dpl
               pop     0FH             ; Retrieve Register Bank 1
               pop     0EH
               pop     0DH
               pop     0CH
               pop     0BH
               pop     0AH
               pop     09
               pop     08
               ret


;====================================================================
; subroutine MULDIV
; 16-Bit x 16-Bit to 32-Bit Product Signed Multiply followed by
; 32-Bit / 16-Bit to 32-Bit Quotient & remainder signed Divide
; 2's Complement Format
;
; input:    r1, r0 = multiplicand X
;           r3, r2 = multiplier Y
;           r5, r4 = divisor Z
;
; output:   r3, r2, r1, r0 = quotient Q of division Q = (X x Y) / Z
;           r7, r6, r5, r4 = remainder
;           Carry C is set if Z = 0, i.e. divide by 0 attempted
;
; calls:    UMUL16, UDIV32, Cr0r1, Cr2r3, Cr4r5, Mr0r3
;
; alters:   acc, flags, Bits 21H & 22H
;====================================================================

MULDIV:        anl     PSW, #0E7H      ; Register Bank 0
               mov     a, r4           ; get divisor high byte
               orl     a, r5           ; OR with low byte
               jnz     muld_OK         ; divisor OK if not 0
               setb    C               ; else, overflow
               ret

muld_OK:       lcall   Cr0r1           ; 2's comp -> Mag/Sign
               lcall   Cr2r3           ; 2's comp -> Mag/Sign
               lcall   UMUL16
               jb      21H, divn1      ; test X sign
divn:          lcall   Cr4r5           ; 2's comp -> Mag/Sign
               lcall   UDIV32
               lcall   Mr0r3           ; Mag/Sign -> 2's Comp
               clr     C               ; divisor is not 0
               ret

divn1:         jbc     22H, divn       ; test Y sign
               setb    22H
               sjmp    divn


;====================================================================
; subroutine MACD16
; 16-Bit x 16-Bit to 32-Bit Product signed Multiply-Accumulate
; with table data and data move.
; y(n) = x(n)*h0 + x(n-1)*h1 + x(n-2)*h2 + ......
; Note: Assumes shared program/data space. i.e. PSEN and RD are OR-ed
; together on the board.
; 2's Complement format
;
; input:    B = No. of 16-bit data items in tables (max 63)
;           DPTR --> New Input data (e.g. from ADC)
;           DPTR+2 --> Base of Data Table (x)
;           DPTR+128 --> Base of Multiplier Table (h)
;
; output:   r7, r6, r5, r4 = 32-bit accumulated result
;
; calls:    MUL16
;
; alters:   acc, flags, Bits 21H & 22H
;====================================================================

MACD16:        anl    PSW, #0E7H
               mov    r4, #0           ; Clear Accumulator
               mov    r5, #0
               mov    r6, #0
               mov    r7, #0

               movx   a, @DPTR
               push   acc              ; Save XNEWL
               inc    DPTR
               movx   a, @DPTR
               push   acc              ; Save XNEWH
               inc    DPTR

Macd1:         movx   a, @DPTR         ; Get x(n)L
               mov    r0, a
               push   acc              ; Save x(n)L
               mov    a, #80H
               movc   a, @a+DPTR       ; Get h(n)L
               mov    r2, a
               inc    DPTR
               movx   a, @DPTR         ; Get x(n)H
               mov    r1, a
               push   acc              ; Save x(n)H
               mov    a, #80H
               movc   a, @a+DPTR       ; Get h(n)H
               mov    r3, a
               lcall  MUL16+3          ; Do Multiply...
               mov    A, r4            ; then Accumulate..
               add    A, r0
               mov    r4, A
               mov    A, r5
               addc   A, r1
               mov    r5, A
               mov    A, r6
               addc   A, r2
               mov    r6, A
               mov    A, r7
               addc   A, r3
               mov    r7, A
               pop    01               ; Now move x data
               pop    00
               pop    03
               pop    02
               push   00
               push   01
               mov    a, r3            ; Move up x(n)H
               movx   @DPTR, a
               mov    a, #0FFH
               add    a, dpl
               mov    dpl, a
               mov    a, #0FFH
               addc   a, dph
               mov    dph, a
               mov    a, r2            ; Move up x(n)L
               movx   @DPTR, a
               inc    DPTR
               inc    DPTR
               djnz   b, Macd1         ; Whole table processed?
               dec    SP
               dec    SP
               ret


;==================================================================
; subroutine DELAY
;
; input:    r0, r1, r2 = delay loop constants, r0 = coarse loop
;==================================================================

DELAY:         push   dpl
               push   dph
               mov    dpl, r1
               mov    dph, r2
Delay1:        mov    r1, dpl
Delay2:        mov    r2, dph
               djnz   r2, $
               djnz   r1, Delay2
               djnz   r0, Delay1
               pop    dph
               pop    dpl
               ret


end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -