Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
Marc Vanvoren
03/14/18 12:32
Read: 113 times


 
#190873 - 16 * 16 bit
Hi,
Here is a nice piece of code to multiply two 16 bit operands, signed and unsigned.
Can someone please explain me the methodology used in the calculation loop.
That is from label "M16_Loop:" to "M16_Calculations done".
All the rest of the code is clear to me except that part.
Thanks a lot!


;----------------------------------------------------------------------------------------
;Function name: mul_16x16_signed
;Description..: Multiplies 2 signed 16-bit operands resulting in a signed 32-bit number.
;				Control flag MathLib_Res1Neg is set with negative result.
;
;
;Function name: mul_16x16_unsigned
;Description..: Multiplies 2 unsigned 16-bit operands resulting in a unsigned 32-bit number.
;
;
;Function name: mul_16x16_signed_op1
;Description..: Multiplies signed 16-bit operand (op1) by 
;				unsigned 16-bit operand (op2) resulting in a signed 32-bit number.
;				Control flag MathLib_Res1Neg is set with negative result.
;
;
;Inputs: Operand 1 HB = MathLib_Op1+0
;				   LB = MathLib_Op1+1
;
;		 Operand 2 HB = MathLib_Op2+0
;				   LB = MathLib_Op2+1
;
;Output:    Result HB = MathLib_Res1+0
;						MathLib_Res1+1
;						MathLib_Res1+2
;				   LB = MathLib_Res1+3
;
;	 Negative result: MathLib_Res1Neg = 1
;------------------------------------------------------------------------------------	
;
mul_16x16_signed:	mov  MathLib_Flags,#0		;Clear control flags
					push b						;Save used registers by routine 
					mov  b,#16					;Initialize loop counter
					jmp  M16_signed_init


mul_16x16_unsigned:	mov  MathLib_Flags,#0		;Clear control flags
					push b						;Save used registers by routine 
					mov  b,#16					;Initialize loop counter
					jmp  M16_unsigned_init


mul_16x16_signed_op1:
					mov  MathLib_Flags,#0		;Clear control flags
					push b						;Save used registers by routine 
					mov  b,#16					;Initialize loop counter
					jmp  M16_signed_op1_init

;----------------------------------------------------------------------------------------	
;Do Calculation
;
M16_signed_init:	mov  a,MathLib_Op2+0		;Is the signed operand 2 negative?
					rlc  a
					jnc  M16_000				;If not, skip complementing
					cpl  MathLib_NegateResult	;Toggle negate result flag
					xrl  MathLib_Op2+1,#0FFh	;Complement operand 2
					xrl  MathLib_Op2+0,#0FFh
					mov  a,MathLib_Op2+1		;Increment operand 2 LB
					add  a,#1
					mov  MathLib_Op2+1,a
					jnc  M16_000				;If carry also increment LB
					inc  MathLib_Op2+0			;Propagate carry into HB
M16_000:			
				
M16_signed_op1_init:	
					mov  a,MathLib_Op1+0		;Is the signed operand 1 negative?
					rlc  a
					jnc  M16_001				;If not, skip complementing
					cpl  MathLib_NegateResult	;Toggle negate result flag
					xrl  MathLib_Op1+1,#0FFh	;Complement operand 1
					xrl  MathLib_Op1+0,#0FFh
					mov  a,MathLib_Op1+1		;Increment operand 1 LB
					add  a,#1
					mov  MathLib_Op1+1,a
					jnc  M16_001				;If carry also increment LB
					inc  MathLib_Op1+0			;Propagate carry into HB
M16_001:			
				
M16_unsigned_init:										;Initialize result 'register'
					mov  MathLib_Res1+3,MathLib_Op2+1	;Put 16-bit multiplier in byte 3 of product/multiplier
					mov  MathLib_Res1+2,MathLib_Op2+0	;Put 16-bit multiplier in byte 2 of product/multiplier
					mov  MathLib_Res1+1,#0				;			  Clear byte 1 of product/multiplier
					mov  MathLib_Res1+0,#0				;			  Clear byte 0 of product/multiplier

M16_loop:			mov  a,MathLib_Res1+3		;Is low bit of multiplier set?
					rrc  a
					jnc  M16_DoShift
				
M16_DoAdd:			mov  a,MathLib_Res1+1		;Upper 16 bits of product/multiplier += multiplicand
					add  a,MathLib_Op1+1		;Add LSB of multiplicand
					mov  MathLib_Res1+1,a
					mov  a,MathLib_Res1+0
					addc a,MathLib_Op1+0		;Add MSB of multiplicand
					mov  MathLib_Res1+0,a

M16_DoShift:		mov  a,MathLib_Res1+0		;Shift entire product/multiplier right once
					rrc  a
					mov  MathLib_Res1+0,a
					mov  a,MathLib_Res1+1
					rrc  a
					mov  MathLib_Res1+1,a
					mov  a,MathLib_Res1+2
					rrc  a
					mov  MathLib_Res1+2,a
					mov  a,MathLib_Res1+3
					rrc  a
					mov  MathLib_Res1+3,a
					djnz b,M16_loop				;Check all loops done

M16_CalculationsDone:
					pop  b						;Restore registers used by routine

M16_CheckNegateResult:
					jnb  MathLib_NegateResult,M16_End	;Should the answer be negative?
					setb MathLib_Res1Neg				;Set bit negative result
					xrl  MathLib_Res1+3,#0FFh			;Yes, complement the answer
					xrl  MathLib_Res1+2,#0FFh
					xrl  MathLib_Res1+1,#0FFh
					xrl  MathLib_Res1+0,#0FFh
					mov  a,MathLib_Res1+3		;Increment result LB
					add  a,#1
					mov  MathLib_Res1+3,a
					jnc  M16_End				;No carry: we're done
					mov  a,MathLib_Res1+2		;Propagate carry into byte 2
					addc a,#0
					mov  MathLib_Res1+2,a
					jnc  M16_End				;No carry: we're done
					mov  a,MathLib_Res1+1		;Propagate carry into byte 1
					addc a,#0
					mov  MathLib_Res1+1,a
					jnc  M16_End				;No carry: we're done
					mov  a,MathLib_Res1+0		;Propagate carry into byte 0
					addc a,#0
					mov  MathLib_Res1+0,a
M16_End:			ret

 



No replies in thread

Back to Subject List