posted to PICList
Something like this: -------------------- mult24x8: clrf prod0 ; Clear the product clrf prod1 clrf prod2 clrf prod3 clrf twofour3 ; Clear the top byte of the multiplicand multloop: movf eight,W ; Check to see if eight bit is empty btfsc STATUS,Z ; Done if zero return bcf STATUS,C ; clear carry rrl eight,F ; Get the next bit btfss STATUS,C ; Add if carry is set goto multshift ; shift only if 0 movf twofour0,W ; Add the 32 bits of multiplicand to product addwf prod0,F ; each addwf sets the carry btfsc STATUS,C ; Don't increment if no carry call carryprop1 ; Propigate carry to next byte(s) movf twofour1,W ; addwf prod1,F ; btfsc STATUS,C ; Don't increment if no carry call carryprop2 ; Propigate carry to next byte(s) movf twofour2,W ; addwf prod2,F ; btfsc STATUS,C ; Don't increment if no carry incf prod3,F ; Add one to next byte if carry occured movf twofour3,W ; addwf prod3,F ; multshift: bcf STATUS,C ; clear carry rlf twofour0,F ; Shift the 24 bits one bit to the left rlf twofour1,F rlf twofour2,F rlf twofour3,F goto multloop carryprop1: incfsz prod1,F return carryprop2: incfsz prod2,F return carryprop3: incf prod3,F return ------------------------------------------------------------ I wrote this off the top of my head and I haven't tested it, but it should be in the ballpark. Not speedy, but should work.
Code:
I worked with this code of Bryon A Jeff to create a 32x8 bit multiplier that gives a 32 bit result, without any carry. The solution is as follow:Variable definitions are done as follow:
cblock 0x73 Multiplier Multiplicant:4 Product:4 MultiCount endcPlease note that the 0x73 address of the variables should be changed to suit your application. The variables take a total of 10 bytes of RAM.The code now looks like this:
;----------------------------- Multiply32x8 ; Clear Product clrf Product clrf Product+1 clrf Product+2 clrf Product+3 ; Test for an 0 multiplier movf Multiplier, W btfsc STATUS, Z return ; Setup the counter for 8 bits movlw 0x08 movwf MultiCount MultiplyLoop rlf Multiplier, F btfss STATUS, C goto ShiftLoop movf Multiplicant+0, W addwf Product+0, F btfsc STATUS, C call CarryByte1 movf Multiplicant+1, W addwf Product+1, F btfsc STATUS, C call CarryByte2 movf Multiplicant+2, W addwf Product+2, F btfsc STATUS, C call CarryByte3 movf Multiplicant+3, W addwf Product+3, F ShiftLoop decfsz MultiCount, F goto $+2 return bcf STATUS, C rlf Product+0, F rlf Product+1, F rlf Product+2, F rlf Product+3, F goto MultiplyLoop CarryByte1 incfsz Product+1, F return CarryByte2 incfsz Product+2, F return CarryByte3 incf Product+3, F return ;----------------------------- To test the multiplication, you can use the following code: movlw 0x7D movwf Multiplicant+0 movlw 0x8E movwf Multiplicant+1 movlw 0xAB movwf Multiplicant+2 movlw 0x7A movwf Multiplicant+3 movlw 0x8F movwf Multiplier call Multiply32x8This does 0x7AAB8E7D times 0x8F, which should result in 0x85D497D3. Please note it does not return 0x4485D497D3, since the 5th byte in the result would have been the carry, which is disgarded. This routine can be used as it is for 24x8 bit multiplication, which will result in a full 32 bit product, with no carry needed. The total instruction cycles to perform the above multiplication is 221. This will vary, according to the complexity of the numbers, but should always be below 1ms which running the PIC at 4Mhz or higher.Hope this code helps anyone.
Interested: