Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
; Multiply 10bit by 10bit unsigned
; by Martin Sturm 2010
; Tested over full range of 10bit input combinations
;
; a (10bit) = aH:aL (not modified)
; b (10bit) = bH:bL (not modified)
; aH:aL * bH:bL --> rH:rM:rL
;
; incorrect result if a or b has non-zero bits above the 10th
; unless optional ANDLW 0x03 is used
;
; Algorithm
; r = a*b
; r = 2^16*(aH*bH) + 2^8*(aH*bL + bH*aL) + aL*bL
; 2x2 2x8 2x8 8x8
; all multiplications are unrolled
;
; 73 instructions, 57-73 cycles, 65 avg
;
; helper macro
mmac MACRO A,bit, uH,uL
BTFSC A,bit
ADDWF uH,F
RRF uH,F
RRF uL,F
ENDM
MULT_10x10 MACRO aH,aL, bH,bL, rH,rM,rL
LOCAL g1, g2, g3, g4
; rM:rL = aL*bL [8x8 bit multiply] (36 cycles)
CLRF rM
CLRF rL
CLRC
MOVFW bL
mmac aL,0, rM,rL
mmac aL,1, rM,rL
mmac aL,2, rM,rL
mmac aL,3, rM,rL
mmac aL,4, rM,rL
mmac aL,5, rM,rL
mmac aL,6, rM,rL
mmac aL,7, rM,rL
; rH = aH*bH [2x2 bit multiply] (8 cycles)
CLRF rH
MOVFW bH ; multiplicand in W
; ANDLW 0x03 ; prevent errors if bH non-zero above 10th bit
BTFSC aH,1 ; carry always clear by here
ADDWF rH,F ; never sets carry
RLF rH,F
BTFSC aH,0
ADDWF rH,F
; rH:rM += aH*bL [2-bit x 8-bit] (7-15 cycles, avg 11)
MOVFW bL ; multiplicand in W
BTFSS aH,0
GOTO g1
ADDWF rM,F ; add bL
SKPNC
INCF rH,F
g1
BTFSS aH,1
GOTO g2
CLRC
RLF bL,W ; W now holds (2*bL & 0xFF)
ADDWF rM,F ; add W to rM
SKPNC
INCF rH,F
BTFSC bL,7 ;
INCF rH,F ; add the upper bit of 2*bL
g2
; rH:rM += bH*aL [2-bit x 8-bit] (7-15 cycles, avg 11)
MOVFW aL ; multiplicand in W
BTFSS bH,0
GOTO g3
ADDWF rM,F ; add aL
SKPNC
INCF rH,F
g3
BTFSS bH,1
GOTO g4
CLRC
RLF aL,W ; W now holds (2*aL & 0xFF)
ADDWF rM,F ; add W to rM
SKPNC
INCF rH,F
BTFSC aL,7 ;
INCF rH,F ; add the upper bit of 2*aL
g4
ENDM
LIST p=16F88 ; list directive to define processor
#INCLUDE <P16F88.INC> ; processor specific variable definitions
ERRORLEVEL 0, -302 ;suppress bank selection messages
;------------------------------------------------------------------------------
; CONFIGURATION WORD SETUP
;------------------------------------------------------------------------------
__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_IO
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
CBLOCK 0x20 ;GPR variable registers allocated contiguously
aH
aL
bH
bL
rH
rM
rL
ENDC
RESET ORG 0x0000 ; processor reset vector
bsf STATUS, RP0 ;select bank 1
movlw 0x07
movwf CMCON ;turn comparators off
movwf OSCCON ;
movlw b'00010011' ;set ra2&3 to digital & RB6 & 7 !!
movwf ANSEL
movlw b'1110011' ;set RA2&3 to output
movwf TRISA
movlw b'00000000' ;set PortB all outputs
movwf TRISB
movlw b'01100000' ;Set up clock speed mhz4
movlw b'01000000'
movlw ADCON1
bcf STATUS, RP0
movlw b'01001001'
movwf ADCON0
clrf PORTA
clrf PORTB
bsf PORTA,2
goto START ; go to beginning of program
START
movlw b'11111111'
movwf aH
movlw b'11000000'
movwf aL
movlw .2
movwf bL
Call Times
goto START
;CODE FROM PICLIST.COM
; Multiply 10bit by 10bit unsigned
; by Martin Sturm 2010
; Tested over full range of 10bit input combinations
;
; a (10bit) = aH:aL (not modified)
; b (10bit) = bH:bL (not modified)
; aH:aL * bH:bL --> rH:rM:rL
;
; incorrect result if a or b has non-zero bits above the 10th
; unless optional ANDLW 0x03 is used
;
; Algorithm
; r = a*b
; r = 2^16*(aH*bH) + 2^8*(aH*bL + bH*aL) + aL*bL
; 2x2 2x8 2x8 8x8
; all multiplications are unrolled
;
; 73 instructions, 57-73 cycles, 65 avg
;
; helper macro
mmac MACRO A,bit, uH,uL
BTFSC A,bit
ADDWF uH,F
RRF uH,F
RRF uL,F
ENDM
MULT_10x10 MACRO aH,aL, bH,bL, rH,rM,rL
LOCAL g1, g2, g3, g4
; rM:rL = aL*bL [8x8 bit multiply] (36 cycles) CLRF rM
CLRF rL
CLRC
MOVFW bL
mmac aL,0, rM,rL
mmac aL,1, rM,rL
mmac aL,2, rM,rL
mmac aL,3, rM,rL
mmac aL,4, rM,rL
mmac aL,5, rM,rL
mmac aL,6, rM,rL
mmac aL,7, rM,rL
; rH = aH*bH [2x2 bit multiply] (8 cycles)
CLRF rH
MOVFW bH ; multiplicand in W
ANDLW 0x03 ; prevent errors if bH non-zero above 10th bit
BTFSC aH,1 ; carry always clear by here
ADDWF rH,F ; never sets carry
RLF rH,F
BTFSC aH,0
ADDWF rH,F
; rH:rM += aH*bL [2-bit x 8-bit] (7-15 cycles, avg 11)
MOVFW bL ; multiplicand in W
BTFSS aH,0
GOTO g1
ADDWF rM,F ; add bL
SKPNC
INCF rH,F
g1
BTFSS aH,1
GOTO g2
CLRC
RLF bL,W ; W now holds (2*bL & 0xFF)
ADDWF rM,F ; add W to rM
SKPNC
INCF rH,F
BTFSC bL,7 ;
INCF rH,F ; add the upper bit of 2*bL
g2
; rH:rM += bH*aL [2-bit x 8-bit] (7-15 cycles, avg 11)
MOVFW aL ; multiplicand in W
BTFSS bH,0
GOTO g3
ADDWF rM,F ; add aL
SKPNC
INCF rH,F
g3
BTFSS bH,1
GOTO g4
CLRC
RLF aL,W ; W now holds (2*aL & 0xFF)
ADDWF rM,F ; add W to rM
SKPNC
INCF rH,F
BTFSC aL,7 ;
INCF rH,F ; add the upper bit of 2*aL
g4
ENDM
GOTO$
END
Note: Macros must be defined before they are used, i.e., forward references to macros are not permitted
This code demonstrates the utility of macro directive, which is used to define a macro.
#include p16f877a.inc ;Include standard header file
;for the selected device.
result equ 0x20 ;Assign value 20H to label
;result.
ORG 0x0000 ;The following code will be placed
;in reset address 0.
goto start ;Jump to an address whose label is
;'start'.
add MACRO num1,num2 ;'add' is a macro. The values of
;'num1' and 'num2' must be passed
;to this macro.
movlw num1 ;Load W register with a literal
;value assigned to the label
;'num1'.
movwf result ;Load W register to an address
;location assigned to the label
;'result'.
movlw num2 ;Load W register with a literal
;value assigned to the label
;'num2'.
addwf result ;Add W register with the memory
;location addressed by 'result'
;and load the result back to
;'result'.
endm ;end of 'add' MACRO
ORG 0x0010 ;Main program starts at 10H.
start ;The label 'start' is assigned an
;address 10H.
add .100,.90 ;Call 'add' MACRO with decimal
;numbers 100 and 90 assigned to
;'num1' and 'num2' labels,
;respactively. 100 and 90 will be
;added and the result will be in
;'result'.
end
radix dec
START
movlw low(1023) ;
movwf aL ;
movlw high(1023) ;
movwf aH ;
movlw low(2) ;
movwf bL ;
movlw high(2) ;
movwf bH ;
call Times ;
goto $ ;
radix dec
START
movlw 1023%256 ; a = 1023
movwf aL ;
movlw 1023/256 ;
movwf aH ;
movlw 2%256 ; b = 2
movwf bL ;
movlw 2/256 ;
movwf bH ;
call Times ; do 10x10 multiply
goto $ ;