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

📄 math8051.asm

📁 A collection of math routines including 8-bit, 16-bit, 32-bit signed and unsigned addition, subtract
💻 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 countdiv_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, dpldiv_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               retdiv32_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 countdiv_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, dpldiv_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               retmuld_OK:       lcall   Cr0r1           ; 2's comp -> Mag/Sign               lcall   Cr2r3           ; 2's comp -> Mag/Sign               lcall   UMUL16               jb      21H, divn1      ; test X signdivn:          lcall   Cr4r5           ; 2's comp -> Mag/Sign               lcall   UDIV32               lcall   Mr0r3           ; Mag/Sign -> 2's Comp               clr     C               ; divisor is not 0               retdivn1:         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    DPTRMacd1:         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, r2Delay1:        mov    r1, dplDelay2:        mov    r2, dph               djnz   r2, $               djnz   r1, Delay2               djnz   r0, Delay1               pop    dph               pop    dpl               retend

⌨️ 快捷键说明

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