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

📄 float1.asm

📁 PIC单片机子程序大全,好东西
💻 ASM
字号:
#define PAGE    EJECT

	TITLE   "Binary Floating Arithmetic Routines For PIC17C42 : Ver 1.0"

	LIST    columns=120, WRAP, L=0
;
	include "17c42.h"
;
;*******************************************************************
;               Binary Floating Point Addition, Subtraction And
;                       Multiplication Routines
;
;  Mantissa = 16 bits
;  Exponent = 8 bits    ( exponent is binary and not decimal)
;                        i.e a number ABCD EXP(X) = 0xABCD * (2**X)
;
;       Before calling any of the following floating point routines,
;  it is required to set Indirect Register 0 ( FSR0 ) for
;  No-Autoincrement ( i.e. Set bits FS0 & FS1 in ALUSTA to 1s)
;
;*******************************************************************;
;
	CBLOCK 0x20
		ACCaLO, ACCaHI, EXPa
		ACCbLO, ACCbHI, EXPb
		ACCcLO, ACCcHI
		ACCdLO, ACCdHI
		temp, sign
	ENDC
;
Mode16  equ     TRUE     ; Change this to FALSE for 32 bit product

	PAGE
;
	ORG     0x0000
;
;*******************************************************************
;                 Floating Point Routines Test Program
;*******************************************************************
;
main
;
	bsf      _fs0            ; set FSR0 for no autoincrement
	bsf      _fs1
;
	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
;
self    goto    self
;
;    Load constant values to (ACCa, EXPa) & (ACCb, EXPb) for testing
;
loadAB
	movlw    0x01
	movwf     ACCaHI
	movlw    0xff             ; loads ACCa = 01FF EXP(4)
	movwf     ACCaLO
	movlw    0x04
	movwf     EXPa
;
	movlw    0x7f
	movwf     ACCbHI
	movlw    0xff             ; loads ACCb = 7fff EXP(6)
	movwf   ACCbLO
	movlw    0x06
	movwf     EXPb
	return
;
	PAGE
;*******************************************************************
;       Floating Point Subtraction  ( ACCb - ACCa -> ACCb )
;
;   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.
;
;*******************************************************************;
;
F_sub
	movlw    ACCaLO
	movwf     fsr0
	call    negate           ; At first negate ACCa; Then addwf
;
;*******************************************************************
;       Floating Point Addition  ( ACCb + ACCa -> ACCb )
;
;   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
;
;*******************************************************************
;
F_add
	movfp    EXPa,wreg
	cpfseq     EXPb
	goto    Lbl1
	goto    noAddNorm          ; if exponents are equal
Lbl1
	cpfslt     EXPb
	call    F_swap          ; if B > A then swap ( A<->B )
	movfp    EXPa,wreg
	subwf     EXPb
scloop
	call    addNorm
	incfsz     EXPb
	goto    scloop
	movfp    EXPa,wreg
	movwf     EXPb
noAddNorm
	movfp    ACCaHI,wreg
	iorwf     ACCbHI,w
	movwf     sign            ; save the sign ( MSB states)
	call    D_add           ; compute double precision integer addwf
	btfss      sign,MSB
	btfss      ACCbHI,MSB
	return
	incf     EXPb
	bcf      _carry
	goto    shftR
;
addNorm
	bcf      _carry
	btfsc      ACCbHI,MSB
	bsf      _carry          ; set carry if < 0
shftR
	rrcf     ACCbHI
	rrcf     ACCbLO
	return
;
	PAGE
;*******************************************************************
;       Double Precision Addition
;
D_add
	movfp    ACCaLO,wreg
	addwf     ACCbLO           ;addwf lsb
	movfp    ACCaHI,wreg
	addwfc    ACCbHI           ;addwf msb with carry
	return
;
	PAGE
;*******************************************************************
;               Binary Floating Point Multiplication
;
;   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.
;
;  If a 32 bit mantissa is desired, set MODE16 equ FALSE
;*******************************************************************
;
F_mpy
	call    S_SIGN
	call    setup
mloop
	bcf      _carry
	rrcf     ACCdHI           ;rotate d right
	rrcf     ACCdLO
	btfsc      _carry
	call    D_add
	rrcf     ACCbHI
	rrcf     ACCbLO
	rrcf     ACCcHI
	rrcf     ACCcLO
	decfsz     temp             ;loop until all bits checked
	goto    mloop
;
	movfp    EXPa,wreg
	addwf     EXPb
;
    #if Mode16
	tstfsz      ACCbHI
	goto    finup           ; if ACCbHI != 0
	tstfsz      ACCbLO
	goto    Shft08          ; if ACCbLO != 0 && ACCbHI == 0
;
	movfp    ACCcHI,wreg
	movwf     ACCbHI          ; if ACCb == 0, then move ACCc to ACCb
	movfp    ACCcLO,wreg
	movwf     ACCbLO
	movlw    16
	addwf     EXPb
	goto    finup
;
Shft08
	movfp    ACCbLO,wreg
	movwf     ACCbHI
	movfp    ACCcHI,wreg
	movwf     ACCbLO
	movlw    8
	addwf     EXPb
;
    #endif                   ; matching endif for IF Mode16
;
finup
	btfss      sign,MSB
	goto    F_norm
;
	movlw    ACCcLO
	movwf     fsr0
	call    negate
	movlw    ACCbLO
	movwf     fsr0
	call    negate
	goto    F_norm          ; normalize floating point
;
;*******************************************************************
;
setup
	clrf     temp
	bsf      temp,4          ; set temp = 16
	movfp    ACCbHI,wreg          ;move ACCb to ACCd
	movwf     ACCdHI
	movfp    ACCbLO,wreg
	movwf     ACCdLO
	clrf     ACCbHI
	clrf     ACCbLO          ; clear ACCb ( ACCbLO & ACCbHI )
	return
;
	PAGE
;*******************************************************************
;       Double Precision Negate Routines
;
negateAlt
	movfp    indf0,wreg
	bcf      _fs1
	negw     indf0
	bsf      _fs1
	movfp    indf0,wreg
	clrf     indf0
	subwfb    indf0
	return
;
negate
	comf    indf0
	bcf      _fs1
	incf     indf0
	bsf      _fs1
	btfsc      _z
	decf     indf0
	comf    indf0
	return
;
	PAGE
;*******************************************************************
;   Check Sign of the Number, if so negate and set the SIGN flag
;
S_SIGN
	movfp    ACCaHI,wreg
	xorwf     ACCbHI,w
	movwf     sign
	btfss      ACCbHI,MSB        ; if MSB set go & negate ACCb
	goto    chek_A
;
	movlw    ACCbLO
	movwf     fsr0
	call    negate
;
chek_A
	btfss      ACCaHI,MSB        ; if MSB set go & negate ACCa
	return
	movlw    ACCaLO
	movwf     fsr0
	call    negate
	return
;
	PAGE
;*******************************************************************
;      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                          ; normalize ACCb
	tstfsz      ACCbHI
	goto    C_norm
	tstfsz      ACCbLO
	goto    C_norm
	return
;
C_norm
	btfsc      ACCbHI,MSB-1
	return
	call    shftSL
	decf     EXPb
	goto    C_norm
;
shftSL
	bcf      _carry
;
    #if   Mode16
	rlcf     ACCcLO
	rlcf     ACCcHI
    #endif
;
	rlcf     ACCbLO
	rlcf     ACCbHI
	bcf      ACCbHI,MSB
	btfsc      _carry
	bsf      ACCbHI,MSB
	return
;
;*******************************************************************
;  Swap ACCa & ACCb   [ (ACCa,EXPa) <--> (ACCb,EXPb) ]
;
F_swap
	movfp    ACCaHI,wreg
	movwf     temp
	movfp    ACCbHI,wreg        ; ACCaHI <--> ACCbHI
	movwf     ACCaHI
	movfp    temp,wreg
	movwf     ACCbHI
;
	movfp    ACCaLO,wreg
	movwf     temp
	movfp    ACCbLO,wreg        ; ACCaLO <--> ACCbLO
	movwf     ACCaLO
	movfp    temp,wreg
	movwf     ACCbLO
;
	movfp    EXPb,wreg
	movwf     temp
	movfp    EXPa,wreg          ; EXPa <--> EXPb
	movwf     EXPb
	movfp    temp,wreg
	movwf     EXPa
	return
;
;*****************************************************************
;               Normalizes A Floating Point Number
;       The number is assumed to be  (LowByte, HighByte, Exp) in
; consecutive locations. Before calling this routine, the address
; of the LowByte should be loaded into FSR0 (indirect register ptr)
;*****************************************************************
;
Normalize
	incf     fsr0
	tstfsz      indf0
	goto    NextNorm1
	decf     fsr0
	tstfsz      indf0
	goto    NextNorm2
	return
NextNorm2
	incf     fsr0
NextNorm1
	btfsc      indf0,MSB-1
	return
	call    shiftNorm
	incf     fsr0
	decf     indf0
	decf     fsr0
	goto    NextNorm1
;
shiftNorm
	bcf      _carry
	incf     fsr0
	rlcf     indf0
	incf     fsr0
	rlcf     indf0
	decf     fsr0
	decf     fsr0
	decf     fsr0
	rlcf     indf0
	incf     fsr0
	rlcf     indf0
	bcf      indf0,MSB
	btfsc      _carry
	bsf      indf0,MSB
	return
;

	END

⌨️ 快捷键说明

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