📄 float.asm
字号:
;*******************************************************************
; Binary Floating Point Addition, Subtraction, Multiplication
; and Divide routines.
;
;*******************************************************************;
;
; Addition : ACCb(16 bits) + ACCa(16 bits) -> ACCb(16 bits)
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) with
; the 8 bit exponent in EXPa.
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) with
; the 8 bit exponent in EXPb.
; (c) CALL F_add
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits ) with
; the 8 bit exponent in EXPb
;
; Program Memory : 55 locations
;
;*******************************************************************;
;
; Subtraction : ACCb(16 bits) - ACCa(16 bits) -> ACCb(16 bits)
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) with
; the 8 bit exponent in EXPa .
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) with
; the 8 bit exponent in EXPb .
; (c) CALL F_sub
; (d) The result is in location ACCbLO & ACCbHI ( 16 bits ) with
; the 8 bit exponent in EXPb.
;
; Program Memory : 61 locations
;
;*******************************************************************;
;
; Multiplication :
; ACCb(16 bits)EXP(b) * ACCa(16 bits)EXPa -> ACCb(16 bits)EXPb
; where, EXP(x) represents an 8 bit exponent.
; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) with
; an 8 bit exponent in location EXPa
; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) with
; an 8 bit exponent in location EXPb
; (c) CALL F_mpy
; (d) The 16 bit result overwrites ACCb(ACCbLO & ACCbHI). The exponent
; is stored in EXPb and the results are normalized.
;
; NOTE : If one needs to get a 32 bit product( & an 8 bit exponent ),
; re assemble the program after changing the line " Mode16 equ TRUE"
; to " Mode16 equ FALSE ".
; If this option is chosen, then the 32 bit result is returned in
; ( ACCbHI, ACCbLO, ACCcHI, ACCcLO ) and the 8 bit exponent in EXPb.
; This method ( with " Mode16 equ FALSE " ) is NOT Recommended.
;
; Program Memory : 102 locations
;
;*******************************************************************;
;
; Division :
; ACCb(16 bits)EXP(b) / ACCa(16 bits)EXP(a) -> ACCb(16 bits)EXP(b)
; with Remainder in ACCc (16 bits)
; (a) Load the Denominator in location ACCaHI & ACCaLO ( 16 bits )
; with exponent in EXPa
; (b) Load the Numerator in location ACCbHI & ACCbLO ( 16 bits )
; with exponent in EXPa
; (c) CALL F_div
; (d) The 16 bit result is in location ACCbHI & ACCbLO
; with exponent in EXPb
; (e) The 16 bit Remainder is in locations ACCcHI & ACCcLO
;
; Program Memory : 86 locations
;
;*******************************************************************;
;
ACCaLO equ 10
ACCaHI equ 11
EXPa equ 12
ACCbLO equ 13
ACCbHI equ 14
EXPb equ 15
ACCcLO equ 16
ACCcHI equ 17
ACCdLO equ 18
ACCdHI equ 19
temp equ 1A
sign equ 1B
;
include "picreg.h"
;
Mode16 equ TRUE ; Change this to FALSE if a 32 bit propduct
; ; is desired for F_mpy routine.
;
org 0
;*******************************************************************
; Floating Point Subtraction ( ACCb - ACCa -> ACCb )
;
F_sub call neg_A ; At first negate ACCa; Then add
;
F_add movf EXPa,w ; scale mantissas
subwf EXPb,w ; find the greater exponent
btfsc STATUS,Z_bit
goto padd ; exponents are equal
btfsc STATUS,CARRY ;
call F_swap ; if A > B then swap ( A<->B )
movf EXPa,w
subwf EXPb
scloop call shftSR
incfsz EXPb
goto scloop
movf EXPa,w
movwf EXPb
padd movf ACCaHI,w
iorwf ACCbHI,w
movwf sign
call D_add ; compute double precision integer add
btfss sign,MSB
btfss ACCbHI,MSB
retlw 0
bcf STATUS,CARRY
incf EXPb
goto shftR
;
;*******************************************************************
; Double Precision Subtraction ( ACCb - ACCa -> ACCb )
;
D_sub call neg_A ; At first negate ACCa; Then add
;
D_add movf ACCaLO,w ; Addition ( ACCb + ACCa -> ACCb )
addwf ACCbLO ;add lsb
btfsc STATUS,CARRY ;add in carry
incf ACCbHI
movf ACCaHI,w
addwf ACCbHI ;add msb
retlw 0
;*******************************************************************
;
;
shftSR bcf STATUS,CARRY
btfsc ACCbHI,MSB
bsf STATUS,CARRY ; set carry if < 0
shftR rrf ACCbHI
rrf ACCbLO
retlw 0
;
shftSL bcf STATUS,CARRY
;
if Mode16
rlf ACCcLO
rlf ACCcHI
endif
;
rlf ACCbLO
rlf ACCbHI
bcf ACCbHI,MSB
btfsc STATUS,CARRY
bsf ACCbHI,MSB
retlw 0
;
;*******************************************************************
; Binary Floating Point Multiplication :
; ACCb(16 bits)EXP(b) * ACCa(16 bits)EXPa -> ACCb(16 bits)EXPb
;
F_mpy
call S_SIGN
call setup
mloop bcf STATUS,CARRY ; clear carry bit ??????????
rrf ACCdHI ;rotate d right
rrf ACCdLO
btfsc STATUS,CARRY ;need to add?
call D_add
rrf ACCbHI
rrf ACCbLO
rrf ACCcHI
rrf ACCcLO
decfsz temp ;loop until all bits checked
goto mloop
;
movf EXPa,w
addwf EXPb
;
IF Mode16
movf ACCbHI
btfss STATUS,Z_bit
goto finup ; if ACCbHI != 0
movf ACCbLO
btfss STATUS,Z_bit
goto Shft08 ; if ACCbLO != 0 && ACCbHI == 0
;
movf ACCcHI,w
movwf ACCbHI ; if ACCb == 0, then move ACCc to ACCb
movf ACCcLO,w
movwf ACCbLO
movlw .16
addwf EXPb
goto finup
;
Shft08 movf ACCbLO,w
movwf ACCbHI
movf ACCcHI,w
movwf ACCbLO
movlw .8
addwf EXPb
;
ENDIF ; matching endif for IF Mode16
;
finup btfss sign,MSB
goto F_norm
;
decf ACCcLO ; negate ACCc
comf ACCcLO
btfsc STATUS,Z_bit
decf ACCcHI
comf ACCcHI
btfsc STATUS,Z_bit
;
neg_B decf ACCbLO ; negate ACCb
comf ACCbLO
btfsc STATUS,Z_bit
decf ACCbHI
comf ACCbHI
;
goto F_norm
;
;
;*******************************************************************
;
setup movlw .16 ; for 16 shifts
movwf temp
movf ACCbHI,w ;move ACCb to ACCd
movwf ACCdHI
movf ACCbLO,w
movwf ACCdLO
clrf ACCbHI
clrf ACCbLO ; clear ACCb ( ACCbLO & ACCbHI )
retlw 0
;
;*******************************************************************
; Floating Point Division :
; ACCb(16 bits)EXP(b) / ACCa(16 bits)EXPa -> ACCb(16 bits)EXPb , with
; remainder in ACCc ( 16 bits ).
;
F_div call S_SIGN
call setup
clrf ACCcHI
clrf ACCcLO
dloop bcf STATUS,CARRY ;????????
rlf ACCdLO
rlf ACCdHI
rlf ACCcLO
rlf ACCcHI
movf ACCaHI,w ; check if ACCa > ACCb
subwf ACCcHI,w
btfss STATUS,Z_bit
goto nochk
movf ACCaLO,w
subwf ACCcLO,w ;if msb equal then check lsb
nochk btfss STATUS,CARRY ;carry set if c>a
goto nogo
movf ACCaLO,w ;c-a into c
subwf ACCcLO
btfss STATUS,CARRY
decf ACCcHI
movf ACCaHI,w
subwf ACCcHI
bsf STATUS,CARRY ;shift a 1 into b (result)
nogo rlf ACCbLO
rlf ACCbHI
decfsz temp ;loop untill all bits checked
goto dloop
movf EXPa,w
subwf EXPb
btfss sign,MSB
goto F_norm
decf ACCbLO ; negate ACCb
comf ACCbLO
btfsc STATUS,Z_bit
decf ACCbHI
comf ACCbHI
goto F_norm
;
;*******************************************************************
;
neg_A comf ACCaLO ; negate ACCa ( -ACCa -> ACCa )
incf ACCaLO
btfsc STATUS,Z_bit
decf ACCaHI
comf ACCaHI
retlw 0
;
;*******************************************************************
;
S_SIGN movf ACCaHI,W
xorwf ACCbHI,W
movwf sign
btfss ACCbHI,MSB ; if MSB set go & negate ACCb
goto chek_A
;
comf ACCbLO ; negate ACCb
incf ACCbLO
btfsc STATUS,Z_bit
decf ACCbHI
comf ACCbHI
;
chek_A btfss ACCaHI,MSB ; if MSB set go & negate ACCa
retlw 0
goto neg_A
;
;*******************************************************************
; Normalize Routine
; Normalizes ACCb for use in floating point calculations.
; Call this routine as often as possible to minimize the loss
; of precission. This routine normalizes ACCb so that the
; mantissa is maximized and the exponent minimized.
;
;
;
F_norm movf ACCbHI
btfss STATUS,Z_bit
goto C_norm
movf ACCbLO
btfsc STATUS,Z_bit
retlw 0
C_norm btfsc ACCbHI,6
retlw 0
call shftSL
decf EXPb
goto C_norm
;
;*******************************************************************
; Swap ACCa & ACCb [ (ACCa,EXPa) <--> (ACCb,EXPb) ]
;
F_swap
movf ACCaHI,w
movwf temp
movf ACCbHI,w ;ACCaHI <--> ACCbHI
movwf ACCaHI
movf temp,w
movwf ACCbHI
;
movf ACCaLO,w
movwf temp
movf ACCbLO,w ;ACCaLO <--> ACCbLO
movwf ACCaLO
movf temp,w
movwf ACCbLO
;
movf EXPa,w
movwf temp
movf EXPb,w ;EXPa <--> EXPb
movwf EXPa
movf temp,w
movwf EXPb
;
retlw 0
;
;*******************************************************************
; Test Program
;*******************************************************************
; Load constant values to (ACCa, EXPa) & (ACCb, EXPb) for testing
;
loadAB movlw 1
movwf ACCaHI
movlw 0FF ; loads ACCa = 01FF EXP(4)
movwf ACCaLO
movlw 04
movwf EXPa
;
movlw 07F
movwf ACCbHI
movlw 0FF ; loads ACCb = 7FFF EXP(6)
movwf ACCbLO
movlw 06
movwf EXPb
retlw 0
;
main nop
;
call loadAB ; result of adding ACCb(EXPb)+ACCa(EXPa)->ACCb(EXPb)
call F_add ; Here Accb = 403F, EXPb = 07
;
call loadAB ; result of subtracting ACCb(EXPb)-ACCa(EXPa)->ACCb(EXPb)
call F_sub ; Here Accb = 7F7F, EXPb = 06
;
call loadAB ; result of multiplying ACCb(EXPb) * ACCa(EXPa)->ACCb(EXPb)
call F_mpy ; Here ACCb = FF7E, EXPb = 12
;
call loadAB ; result of dividing ACCb(EXPb) / ACCa(EXPa)->ACCb(EXPb) with
call F_div ; remainder in ACCc. Here ACCb =4000, EXPb = FA (same as -6)
; ; & the remainder ACCc = 003F
;
self goto self
;
org PIC54
goto main
END
;****************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -