85 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			85 lines
		
	
	
	
		
			1.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| .define .mli2
 | |
| .sect .text
 | |
| .sect .rom
 | |
| .sect .data
 | |
| .sect .bss
 | |
| .sect .text
 | |
| 
 | |
| !  16 bits signed integer multiply
 | |
| !  the algorithm multiples A * B, where A = A0*2^8 + A1 and B = B0*2^8 + B1
 | |
| !  product is thus A0*B0*2^16 + 2^8 * (A0 * B1 + B0 * A1) + A0 * B0
 | |
| !  hence either A0 = 0 or B0 = 0 or overflow.
 | |
| !  initial part of code determines which high byte is 0 (also for negative #s)
 | |
| !  then the multiply is reduced to 8 x 16 bits, with the 8 bit number in the
 | |
| !  a register, the 16 bit number in the hl register, and the product in de
 | |
| !  Expects operands on stack
 | |
| !  Yields result in de-registers
 | |
| 
 | |
| .mli2:	pop h
 | |
| 	shld .retadr	! get the return address out of the way
 | |
| 	lxi h,255
 | |
| 	pop d
 | |
| 	mov a,d		! check hi byte for 0
 | |
| 	cmp h		! h = 0
 | |
| 	jz 1f		! jump if de is a positive 8 bit number
 | |
| 	cmp l
 | |
| 	jz 5f		! jump if de is a negative 8 bit number
 | |
| 	xchg
 | |
| 	shld .tmp1	! we ran out of scratch registers
 | |
| 	pop h
 | |
| 	mov a,h
 | |
| 	cmp e
 | |
| 	jz 7f		! jump if second operand is 8 bit negative
 | |
| 	jmp 6f		! assume second operand is 8 bit positive
 | |
| 
 | |
| 1:	mov a,e		! 8 bit positive number in a
 | |
| 	pop h		! 16 bit number in hl
 | |
| 
 | |
| ! here is the main loop of the multiplication.  the a register is shifted
 | |
| ! right 1 bit to load the carry bit for testing.
 | |
| ! as soon as the a register goes to zero, the loop terminates.
 | |
| ! in most cases this requires fewer than 8 iterations.
 | |
| 2:	lxi d,0
 | |
| 	ora a
 | |
| 3:	rar		! load carry bit from a
 | |
| 	jnc 4f		! add hl to de if low bit was a 1
 | |
| 	xchg
 | |
| 	dad d
 | |
| 	xchg
 | |
| 4:	dad h
 | |
| 	ora a		! sets zero correct and resets carry bit
 | |
| 	jnz 3b		! if a has more bits, continue the loop
 | |
| 	lhld .retadr	! go get return address
 | |
| 	pchl
 | |
| 
 | |
| ! the 8 bit operand is negative. negate both operands
 | |
| 5:	pop h
 | |
| 	mov a,l
 | |
| 	cma
 | |
| 	mov l,a
 | |
| 	mov a,h
 | |
| 	cma
 | |
| 	mov h,a
 | |
| 	inx h		! 16 bit negate is 1s complement + 1
 | |
| 	xra a
 | |
| 	sub e		! negate 8 bit operand
 | |
| 	jmp 2b
 | |
| 
 | |
| ! second operand is small and positive
 | |
| 6:	mov a,l
 | |
| 	lhld .tmp1
 | |
| 	jmp 2b
 | |
| 
 | |
| ! second operand is small and negative
 | |
| 7:	mov e,l
 | |
| 	lhld .tmp1
 | |
| 	mov a,l
 | |
| 	cma
 | |
| 	mov l,a
 | |
| 	mov a,h
 | |
| 	cma
 | |
| 	mov h,a
 | |
| 	inx h
 | |
| 	xra a
 | |
| 	sub e
 | |
| 	jmp 2b
 |