I need to multiply to numbers, but without using the MUL instruction in Assembly 8086.
For example:
mov bx, 2
bx -> bx * 41; code instead this line
Any Help?
I need to multiply to numbers, but without using the MUL instruction in Assembly 8086.
For example:
mov bx, 2
bx -> bx * 41; code instead this line
Any Help?
Use one of the numbers as the counter and add
that many times the other number to the result.
What's important here is that the result needs to be dimensioned to twice the size of the original numbers. If both numbers are 16-bit, then the result must be 32-bit.
Next it's better to use the smallest of both numbers as the counter. This will reduce the number of iterations.
Also don't forget to not start the loop if the counter is zero. Then obviously the product is zero.
mov bx, [Num1]
mov cx, [Num2]
cmp cx, bx
jb ClearResult
xchg bx, cx ;Puts smaller number in CX
ClearResult:
xor ax, ax ;Clear 32-bit result
cwd
jcxz OK
AddAgain:
add ax, bx
adc dx, 0
dec cx
jnz AddAgain
OK:
Here the product is in DX:AX
.
To multiply a variable for a constant, you can, when it is convenient, decompose the constant into powers of 2; for example AX = AX * 320, 320 = 2 ^ 8 + 2 ^ 6. Then make a shift to the left of the variable for each power and a sum. AX = AX * 320 becomes: AX = AX << 8 + AX << 6, but AX << 8 = (AX << 6) << 2. If you want to multiply for a negative constant, you can apply same method but you must negate input before.
As said by Fifoernik, if you want to multiply a 16 bit register for a constant, you may need up to 32 bit result (furthermore you can have negative input-number); all the routines I've written are successfully tested and they are about three time more fast than IMUL (8086 assembly guides of Peter Norton):
Example A; multiply AX for 41:
Function Mul41(Inp:Integer):LongInt; Assembler;
Asm
Mov AX,Inp
{ DX:AX=AX*41; 41=32+8+1.
BX, CX=TEMP}
{05} CWD {DX:AX<-INPUT}
{02} Mov BX,AX
{02} Mov CX,DX
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<3}
{03} Add BX,AX
{03} AdC CX,DX
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<5}
{03} Add AX,BX
{03} AdC DX,CX {DX:AX<-INPUT*(32+8+1)}
{41 CPU clock-cycles}
{128-154 CPU clock-cycles for IMUL RX}
End;
Example B; multiply AX for -41:
Function MulM41(Inp:Integer):LongInt; Assembler;
Asm
Mov AX,Inp
{ DX:AX=AX*-41; 41=32+8+1.
BX, CX=TEMP}
{05} CWD {DX:AX<-INPUT}
{03} Not AX {Because NEG AX before CWD ...}
{03} Not DX {... is wrong for AX=-32768 ...}
{03} Add AX,1 {... it does a two complement of DX:AX}
{03} AdC DX,0 {DX:AX<- -INPUT}
{02} Mov BX,AX
{02} Mov CX,DX {CX:BX<- -INPUT}
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<- -INPUT<<3}
{03} Add BX,AX
{03} AdC CX,DX {CX:BX<- -INPUT*(8+1)}
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<- -INPUT<<5}
{03} Add AX,BX
{03} AdC DX,CX {DX:AX<- -INPUT*(32+8+1)}
{53 CPU clock-cycles}
{128-154 CPU clock-cycles for IMUL RX}
End;
Example 1B; multiply AX for 320:
Function Mul320(Inp:Integer):LongInt; Assembler;
Asm
Mov AX,Inp
{ DX:AX=AX*320; 320=256+64.
BX, CX=TEMP}
{02} ShL AX,1
{03} SBB DX,DX
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<6}
{02} Mov BX,AX
{02} Mov CX,DX {CX:BX<-INPUT<<6}
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<8}
{03} Add AX,BX
{03} AdC DX,CX {DX:AX<-INPUT*(256+64)}
{43 CPU clock-cycles}
{128-154 CPU clock-cycles for IMUL RX}
End;
Example 2B; multiply AX for 200:
Function Mul200(Inp:Integer):LongInt; Assembler;
Asm
Mov AX,Inp
{ DX:AX=AX*200; 200=128+64+8.
BX, CX=TEMP}
{02} ShL AX,1
{03} SBB DX,DX
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<3}
{02} Mov BX,AX
{02} Mov CX,DX {CX:BX<-INPUT<<3}
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<6}
{03} Add BX,AX
{03} AdC CX,DX {CX:BX<-INPUT*(64+8)}
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<7}
{03} Add AX,BX
{03} AdC DX,CX {DX:AX<-INPUT*(128+64+8)}
{45 CPU clock-cycles}
{128-154 CPU clock-cycles for IMUL RX}
End;
Example 3B; multiply AX for 100:
Function Mul100(Inp:Integer):LongInt; Assembler;
Asm
Mov AX,Inp
{ DX:AX=AX*100; 100=64+32+4.
BX, CX=TEMP}
{02} ShL AX,1
{03} SBB DX,DX
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<2}
{02} Mov BX,AX
{02} Mov CX,DX {CX:BX<-INPUT<<2}
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<5}
{03} Add BX,AX
{03} AdC CX,DX {CX:BX<-INPUT*(32+4)}
{02} ShL AX,1
{02} RCL DX,1 {DX:AX<-INPUT<<6}
{03} Add AX,BX
{03} AdC DX,CX {DX:AX<-INPUT*(64+32+4)}
{41 CPU clock-cycles}
{128-154 CPU clock-cycles for IMUL RX}
End;
If you don't need a 32 bit result (only for positive numbers):
Example 1; multiply AX for 320:
{ AX=AX*320; 320=256+64.
BX, CL=TEMP}
Mov CL,6
ShL AX,CL {AX<-INPUT<<6}
Mov BX,AX
Mov CL,2
ShL AX,CL {AX<-INPUT<<8}
Add AX,BX {AX<-AX*(256+64)}
Example 2; multiply AX for 200:
{ AX=AX*200; 200=128+64+8.
BX, CL=TEMP}
Mov CL,3
ShL AX,CL {AX<-INPUT<<3}
Mov BX,AX
ShL AX,CL {AX<-INPUT<<6}
Add BX,AX
ShL AX,1 {AX<-INPUT<<7}
Add AX,BX {AX<-AX*(128+64+8)}
Example 3; multiply AX for 100:
{ AX=AX*100; 100=64+32+4.
BX, CL=TEMP}
Mov CL,2
ShL AX,CL {AX<-INPUT<<2}
Mov BX,AX
Mov CL,3
ShL AX,CL {AX<-INPUT<<5}
Add BX,AX
ShL AX,1 {AX<-INPUT<<6}
Add AX,BX {AX<-AX*(64+32+4)}