?? extras.asm
字號:
;
; 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 + -