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

📄 extras.asm

📁 mcs51,2051,x86系列MCU
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;
;       OPTIMIZED ASSEMBLY ROUTINES FOR INTEGER MATH.
;


;       Excerpts published by permission of Addison Wesley, from the book
;       titled "Programming and interfacing the 8051 microcontroller"
;       ISBN #0-201-63365-5

;===============================================================
; subroutine TC2AV_SB8
; 8-Bit Two's Complement to Absolute Value / Sign Bit Conversion
;
; input:     internal register XT holds a signed byte in two's
;          complement convension
; output:     internal register XA holds the absolute value of the
;          signed byte, addressable bit XS holds the sign (XS is
;          set if XT is a negative number)
; destroys:     a
;================================================================
TC2AV_SB8:
     mov     a, XT          ; read X into accumulator
     jb     acc.7, Xneg     ; X is negative if bit 7 is 1

     mov     XA, XT     ; else, XT is the absolute value
     clr     XS          ; clear sign bit for 'positive'
     ret               ; done
Xneg:
     cpl     a          ; X is negative so find absolute value
     inc     a          ; XA = copmlement(XT)+1
     mov     XA, a          ; save absolute value
     set     XS          ; set sign bit for 'negative'
     ret


;====================================================================
; subroutine AV_SB2TC8
; 8-Bit Absolute Value / Sign Bitto Two's Complement Conversion
;
; input:     internal register XA holds the absolute value of the
;          signed byte, addressable bit XS holds the sign (XS is
;          set if XT is a negative number)
; output:     internal register XT holds a signed byte in two's
;          complement convension.  the addressable bit XOV is
;          set if the byte is out of range (-128 to 127).
; destroys:     a
;====================================================================
AV_SB2TC8:
     mov     a, XA               ; get absolute value
     jnb     acc.7, range_OK     ; see if MSB is 0
     cjne     a, #80h, range_error
     jb     XS, range_OK     ; also error if X is positive

range_error:
     setb     XOV          ; set overflow bit
     ret

range_OK:
     clr     XOV          ; no overflow error
     jb     XS, Xneg1     ; check sign
     mov     XT, XA     ; if positive, XT is the same as XA
     ret               ; done
Xneg1:
     mov     a, XA          ; if X is negative, get its absolute value
     cpl     a          ; complement absolute value of X
     inc     a          ; XT = copmlement(XA)+1
     mov     XT, a          ; save two's complement representation
     ret


;===============================================================
; subroutine TC2AV_SB16
; 16-Bit Two's Complement to Absolute Value / Sign Bit Conversion
;
; input:     internal registers XTH and XTL hold a signed word in
;          two's complement convension
; output:     internal registers XAH and XAL hold the absolute
;          value of the signed word, addressable bit XS holds
;          the sign (XS is set if XT is a negative number)
; destroys:     a
;================================================================
TC2AV_SB16:
     mov     a, XTH     ; read X high byte into accumulator
     jb     acc.7, Xneg     ; X is negative if bit 7 is 1

     mov     XAH, XTH     ; else, XT is the absolute value
     mov     XAL, XTL
     clr     XS          ; clear sign bit for 'positive'
     ret               ; done
Xneg:
     mov     a, XTL     ; X is negative
     cpl     a          ; find its absolute value
     inc     a          ; XA = copmlement(XT)+1
     mov     XAL          ; XAL is found
     jnz     XL_OK          ; if not 0, high byte is not incremented

     mov     a, XTH     ; else get high byte
     cpl     a          ; complement high byte...
     inc     a          ; ... and increment
     mov     XAH          ; store in XAH
     ret               ; done
XL_OK:
     mov     a, XTH     ; get high byte
     cpl     a          ; complement high byte - do not increment
     mov     XAH          ; store in XAH
     ret               ; done

;====================================================================
; subroutine AV_SB2TC16
; 16-Bit Absolute Value / Sign Bit to Two's Complement Conversion
;
; input:     internal registers XAH and XAL hold the absolute
;          value of the signed word, addressable bit XS holds
;          the sign (XS is set if XT is a negative number)
; output:     internal registers XTH and XTL hold a signed word in
;          two's complement convension.  the addressable bit XOV is
;          set if the byte is out of range (-32768 to 32767).
; destroys:     a
;====================================================================
AV_SB2TC16:
     mov     a, XAH          ; get absolute value
     jnb     acc.7, range_OK1     ; see if MSB is 0
     clr     acc.7               ; see if X=-8000h
     orl     a, XAL          ; acc=0 only if X=8000
     jnz     range_error1     ; else error
     jb     XS, range_OK1     ; also error if X is positive

range_error1:
     setb     XOV          ; set overflow bit
     ret

range_OK1:
     clr     XOV          ; no overflow error
     jb     XS, Xneg2     ; check sign
     mov     XTH, XAH     ; if positive, XT is the same as XA
     mov     XTL, XAL
     ret               ; done
Xneg2:
     mov     a, XAL     ; if X is negative, get its absolute value
     cpl     a          ; complement
     inc     a          ; XT = copmlement(XA)+1
     mov     XTL, a
     jnz     XL_OK1     ; if not 0, high byte is not incremented

     mov     a, XAH     ; else get high byte
     cpl     a          ; complement high byte...
     inc     a          ; ... and increment
     mov     XTH          ; store in XTH
     ret               ; done
XL_OK1:
     mov     a, XAH     ; get high byte
     cpl     a          ; complement high byte - do not increment
     mov     XTH          ; store in XTH
     ret               ; done

;===============================================================
; subroutine SMUL8
; 8-Bit Multiplication of Signed Integers in the Absolute Value
; / Sign Bit Format
;
; input:     internal registers XA and YA hold the absolute
;          values of the signed bytes X and Y.  addressable
;          bits XS and YS hold the sign bits, set if the
;          corresponding numbers are negative
; output:     internal registers ZAH and ZAL hold the absolute
;          value of the result Z=X碮.  addressable bit ZS
;          holds the sign of the result, set if the result is
;          negative.
; destroys:     a
;================================================================
SMUL8:
     mov     a, XA          ; read X and ...
     mov     b, YA          ; ... Y
     mul     ab          ; multiply X and Y
     mov     ZH, b          ; save result high ...
     mov     ZL, a          ; ... and low byte

     mov     C, XS          ; get sign of X
     xrl     C, YS          ; compute sign of result Z
     mov     ZS, C          ; save sign of result
     ret

;===============================================================
; subroutine SDIV8
; 8-Bit Division of Signed Integers in the Absolute Value /
; Sign Bit Format
;
; input:     internal registers XA and YA hold the absolute
;          values of the signed bytes X and Y.  addressable
;          bits XS and YS hold the sign bits, set if the
;          corresponding numbers are negative
; output:     internal registers ZAQ and ZAR hold the quotient and
;          the remainder of the division Z=X竃.  addressable
;          bit ZS holds the sign of the result, set if the
;          result is negative.  the addressible bit ZOV is set
;          if Y is zero.
; destroys:     a
;================================================================
SDIV8:
     mov     a, XA          ; read X and ...
     mov     b, YA          ; ... Y
     div     ab          ; divide X and Y
     mov     C, OV          ; get overflow flag
     mov     ZOV, C     ; save in ZOV.  (set if Y=0)
     mov     ZAQ, a     ; save result quotient
     mov     ZAR, a     ; save remainder

     mov     C, XS          ; get sign of X
     xrl     C, YS          ; compute sign of result Z
     mov     ZS, C          ; save sign of result
     ret

;====================================================================
; subroutine ADD16
; 16-Bit Unsigned Addition
;
; input:     internal registers XH, XL, YH, and YL hold the high and
;          low bytes of the unsigned words
; output:     internal registers ZH and ZL hold high and low bytes of
;          the unsigned word Z=X+Y.  addressible bit ZOV is set if
;          the result (Z) is out of range (an external carry is
;          produced from the high byte)
; destroys:     a, flags
;====================================================================
ADD16:
     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     ZOV, C     ; set ZOV if external carry
     ret               ; done


;====================================================================
; subroutine SUB16
; 16-Bit Unsigned subtraction
;
; input:     internal registers XH, XL, YH, and YL hold the high and
;          low bytes of the unsigned words
; 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 (if an external barrow is
;          produced)
; destroys:     a, flags
;====================================================================
SUB16:
     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     ZOV, C     ; set ZOV id an external barrow is produced
     ret               ; done
;====================================================================
; subroutine SUB32
; 32-Bit Unsigned subtraction
;
; input:     internal registers X3, X2, X1, X0, and Y3, Y2, Y1, and Y0
;          hold the 32-bit unsigned integers
; output:     internal registers Z3, Z2, Z1, and Z0 hold the result
;          Z=X-Y.  addressible bit ZOV is set if the result (Z) is
;          out of range (if an external barrow is produced)
; destroys:     a, flags
;====================================================================
SUB32:
     mov     a, X0          ; load X low byte into accumulator
     clr     C          ; clear carry flag
     subb     a, Y0          ; subract Y low byte
     mov     Z0, a          ; put result in Z low byte
     mov     a, X1          ; repeat with other bytes...
     subb     a, Y1
     mov     a, X2
     subb     a, Y2
     mov     a, X3
     subb     a, Y3
     mov     ZOV, C     ; set ZOV id an external barrow is produced
     ret               ; done
;====================================================================
; subroutine BMW
; Byte Multiplied by 16-Bit Word
;
; input:     internal register X holds the 8-bit unsigned integer.
;          internal registers YH, and YL hold the high and
;          low bytes of the unsigned word.
; output:     internal registers Z2, Z1 and Z0 hold the three result
;          bytes.  Z2 is the most significant byte, and Z0, the least
;          significant.  The result always fits in 3 bytes.
; destroys:     a, b, r0, flags
;====================================================================
BMW:
     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 MUL16
; Multiply two 16-Bit Unsigned Words
;
; input:     internal register XH, XL, YH, and YL hold the high and
;          low bytes of the two unsigned words X and Y.
; output:     internal registers Z3, Z2, Z1 and Z0 hold the four result
;          bytes.  Z3 is the most significant byte, and Z0, the least
;          significant.  The result always fits in 4 bytes.
; destroys:     a, b, r0, r1, flags
;====================================================================
MUL16:
     lcall BMW          ; multiply XL with (YH:YL)
     mov     a, Z2
     push     acc          ; push ZL2
     mov     a, Z1
     push     acc          ; push ZL1
     mov     a, Z0

⌨️ 快捷键说明

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