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

📄 extras.asm

📁 mcs51,2051,x86系列MCU
💻 ASM
📖 第 1 页 / 共 2 页
字号:
     push     acc          ; push ZL0

     mov     XL, XH     ; put XH in XL
     lcall     BMW          ; multiply XH with (YH:YL)

     mov     b, Z0          ; save ZH0 in b register
     pop     Z0          ; recall ZL0
     pop     a          ; restore ZL1 in accumulator
     add     a, b          ; add ZH0 and ZL1
     mov     b, ZH1     ; save ZH1 in b register
     mov     Z1, a          ; save result
     pop     a          ; restore ZL2 in accumulator
     addc     a, b          ; add ZH1 and ZL2 with carry from ZH0+ZL1
     mov     b, Z2          ; save ZH2 in b register
     mov     Z2, a          ; save ZH1+ZL2+C in Z2
     clr     a          ; clear accumulator
     addc     a, b          ; add ZH2 with carry from ZH1+ZL2
     mov     Z3, a          ; save result
     ret               ; done

     mov     a, X          ; load X into accumulator
     mov     b, YL          ; load Y low byte into b register
     mul     ab          ; multiply
     mov     Z0, a          ; save result low byte
     push     b          ; push result high byte
                    ; this byte needs to be added to the low
                    ; byte of the product X*YH

     mov     a, X          ; load X into accumulator
     mov     b, YH          ; load Y high byte into b register
     mul     ab          ; multiply
     pop     r0          ; recall X*YL high byte
     add     a, r0          ; add X*YL high byte and X*YH low byte
     mov     Z1, a          ; save result
     clr     a          ; clear accumulator
     addc     a, b          ; a = b + carry flag
     mov     Z2, a          ; save result
     ret               ; done

;====================================================================
; subroutine DIV16
; 16-Bit Unsigned Division
;
; input:     internal registers XH, XL, YH, and YL hold the high and
;          low bytes of the unsigned dividend and divisor.
; output:     internal registers Z3 and Z2 hold high and low bytes of
;          the quotient of Z=X竃.  internal registers Z1 and Z0 hold
;          the high and low bytes of the remainder.  addressible bit
;          ZOV is set if Y=0, i.e., the result is out of range.
;
;          r1 and r0 store the high and low bytes of the partial
;          remainder.  r3 and r2 hold the partially computed quotient.
;
; calls:     SUB16
; destroys:     a, r0, r1, r2, r3, r7, flags
;====================================================================
DIV16:
     mov     a, YH               ; get divisor high byte
     orl     a, YL               ; OR with low byte
     jnz     div_OK          ; divisor OK if not 0
     setb     ZOV               ; else, overflow
     ret
div_OK:
     mov     r1, XH          ; store dividend in r1, r0
     mov     r0, XL
     mov     XH, #0          ; clear partial remainder
     mov     XL, #0
     mov     r3, #0          ; clear partial quotient
     mov     r2, #0
     mov     r7, #16          ; set loop count

div_loop:
     clr     C               ; clear carry flag
     mov     a, r0               ; shift the highest bit of the dividend...
     rlc     a               ; ... into...
     mov     r0, a
     mov     a, r1
     rlc     a
     mov     r1, a

     mov     a, XL               ; ... the lowest bit of the partial ...
     rlc     a               ; ... remainder
     mov     XL, a
     mov     a, XH
     rlc     a
     mov     XH, a

     lcall     SUB16               ; attempt to subtract to see if the...
                         ; ... partial remainder is as large or...
                         ; ... larger than the divisor.

     mov     C, ZOV          ; get subtraction external barrow
     cpl     C               ; complement external barrow
     mov     a, r3               ; add result bit to partial quotient
     rrc     a
     mov     r3, a
     mov     a, r2
     rrc     a
     mov     r2, a
     djnz     r7, div_loop

     mov     Z3, r3          ; put quotient in Z3, and Z2
     mov     Z2, r2
     mov     Z1, XH          ; get remainder, saved before the...
     mov     Z0, XL          ; last subtraction
     clr     ZOV               ; divisor is not 0
     ret                    ; done

;====================================================================
; subroutine DIV32
; 32-Bit Unsigned Division
;
; input:     internal registers X3, X2, X1, and X0 hold the 32-bit
;          unsigned dividend.  similarly, internal registers Y1 and
;          Y0 hold the high and low bytes of the unsigned divisor.
;
; output:     internal registers Z5, Z4, Z3, and Z2 hold the 32-bit
;          quotient of Z=X竃.  internal registers Z1 and Z0 hold
;          the high and low bytes of the remainder.  addressible bit
;          ZOV is set if Y=0, i.e., the result is out of range.
;
;          internal registers PR3, PR2, PR1, and PR0 store the
;          partial remainder.  r5, r4, r3, and r2 hold the partially
;          computed quotient.
;
; calls:     SUB16
; destroys:     a, r2, r3, r4, r5, r7, flags
;====================================================================
DIV32:
     mov     a, Y1               ; get divisor high byte
     orl     a, Y0               ; OR with low byte
     jnz     div32_OK          ; divisor OK if not 0
     setb     ZOV               ; else, overflow
     ret
div32_OK:
     mov     Y2, #0          ; high 16 bits of Y is 0
     mov     Y3, #0
     mov     PR3, X3          ; store dividend
     mov     PR2, X2
     mov     PR1, X1
     mov     PR0, X0
     mov     X3, #0          ; clear partial remainder
     mov     X2, #0
     mov     X1, #0
     mov     X0, #0
     mov     r3, #0          ; clear partial quotient
     mov     r2, #0
     mov     r7, #32          ; set loop count

div32_loop:
     clr     C               ; clear carry flag
     mov     a, PR0          ; shift the highest bit of the dividend...
     rlc     a               ; ... into...
     mov     PR, a
     mov     a, PR1
     rlc     a
     mov     PR1, a
     mov     a, PR2
     rlc     a
     mov     PR2, a
     mov     a, PR3
     rlc     a
     mov     PR3, a

     mov     a, X0               ; ... the lowest bit of the partial ...
     rlc     a               ; ... remainder
     mov     X0, a
     mov     a, X1
     rlc     a
     mov     X1, a
     mov     a, X2
     rlc     a
     mov     X2, a
     mov     a, X3
     rlc     a
     mov     X3, a

     lcall     SUB32               ; attempt to subtract to see if the...
                         ; ... partial remainder is as large or...
                         ; ... larger than the divisor.

     mov     C, ZOV          ; get subtraction external barrow
     cpl     C               ; complement external barrow
     mov     a, r5               ; add result bit to partial quotient
     rrc     a
     mov     r5, a
     mov     a, r4
     rrc     a
     mov     r4, a
     mov     a, r3
     rrc     a
     mov     r3, a
     mov     a, r2
     rrc     a
     mov     r2, a

     djnz     r7, div32_loop

     mov     Z5, r5          ; put quotient in Z3, and Z2
     mov     Z4, r4
     mov     Z3, r3
     mov     Z2, r2
     mov     Z1, X1          ; get remainder, saved before the...
     mov     Z0, X0          ; last subtraction
     clr     ZOV               ; divisor is not 0
     ret                    ; done

;====================================================================
; subroutine SADD16
; 16-Bit Signed (Two's Complement) addition
;
; input:     internal registers XH, XL, YH, and YL hold the high and
;          low bytes of the signed words in two's complement
;          convension
; output:     internal registers ZH and ZL hold high and low bytes of
;          the signed word Z=X+Y.  addressible bit ZOV is set if
;          the result (Z) is out of range (-32768 to 32767)
; destroys:     a, flags
;====================================================================
SADD16:
     mov     a, XL          ; load X low byte into accumulator
     add     a, YL          ; add Y low byte
     mov     ZL, a          ; put result in Z low byte
     mov     a, XH          ; load X high byte into accumulator
     addc     a, YH          ; add Y high byte with the carry from low ...
                    ; ... byte operation
      mov     ZH, a          ; save result in Z high byte
     mov     C, OV          ; get the overflow flag and ...
     mov     ZOV, C     ; ... transfer to bit ZOV
     ret               ; done


;====================================================================
; subroutine SSUB16
; 16-Bit Signed (Two's Complement) subtraction
;
; input:     internal registers XH, XL, YH, and YL hold the high and
;          low bytes of the signed words in two's complement
;          convension
; output:     internal registers ZH and ZL hold high and low bytes of
;          the signed word Z=X-Y.  addressible bit ZOV is set if
;          the result (Z) is out of range (-32768 to 32767)
; destroys:     a, flags
;====================================================================
SSUB16:
     mov     a, XL          ; load X low byte into accumulator
     clr     C          ; clear carry flag
     subb     a, YL          ; subract Y low byte
     mov     ZL, a          ; put result in Z low byte
     mov     a, XH          ; load X high byte into accumulator
     subb     a, YH          ; subtract Y high byte with the barrow ...
                    ; ... from low byte operation
     mov     ZH, a          ; save result in Z high byte
     mov     C, OV          ; get the overflow flag and ...
     mov     ZOV, C     ; ... transfer to bit ZOV
     ret               ; done

;===============================================================
; subroutine SMUL16
; multiplication of signed 16-Bit words in the Absolute Value /
; Sign Bit format
;
; input:     internal registers XH, XL and YH, YL hold the
;          magnitudes of the two signed words to be multiplied.
;          The addressible bits XS and YS are set if the
;          corresponding number is negative.
; output:     the absolute value of the result is placed in the 4
;          internal registers named Z3, Z2, Z1, and Z0.
;          Addressable bit ZS is set if the result is negative.
; calls:     MUL16
; destroys:     a
;================================================================
SMUL16:
     lcall     MUL16          ; multiply absolute values
     mov     C, XS          ; get sign of X
     xrl     C, YS          ; exor with the sign of Y
     mov     ZS, C          ; save as sign of the result
     ret

;===============================================================
; subroutine SDIV16
; division of signed 16-Bit words in the Absolute Value / Sign
; Bit format
;
; input:     internal registers XAH, XAL and YAH, YAL hold the
;          magnitudes of the two signed words.  the addressable
;          bits XS and YS are set if the corresponding number is
;          negative.
; output:     the absolute value of the result Z=X竃 is placed in
;          the 4 internal registers named Z3, Z2, Z1, and Z0.
;          addressable bit ZS is set if the result is negative,
;          and ZOV is set if Y=0.
; calls:     DIV16
; destroys:     a
;================================================================
SDIV16:
     lcall     DIV16          ; multiply absolute values
     mov     C, XS          ; get sign of X
     xrl     C, YS          ; exor with the sign of Y
     mov     ZS, C          ; save as sign of the result
     ret


;===============================================================
; subroutine SDIV16
; division of signed 16-Bit words in the Absolute Value / Sign
; Bit format
;
; input:     internal registers XH, XL and YH, YL hold the
;          magnitudes of the two signed words.  the addressable
;          bits XS and YS are set if the corresponding number is
;          negative.
; output:     the absolute value of the result Z=X竃 is placed in
;          the 4 internal registers named Z3, Z2, Z1, and Z0.
;          addressable bit ZS is set if the result is negative,
;          and ZOV is set if Y=0.
; calls:     DIV16
; destroys:     a
;================================================================
SDIV16:
     lcall     DIV16          ; multiply absolute values
     mov     C, XS          ; get sign of X
     xrl     C, YS          ; exor with the sign of Y
     mov     ZS, C          ; save as sign of the result
     ret
;====================================================================
; subroutine FMUL
; multiply two floating point numbers
;
; input:     internal registers X2, X1, X0 and Y2, Y1, Y0 hold the
;          two floating point numbers to be multiplied.
; output:     the product Z = X 

⌨️ 快捷键说明

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