在Assembly中实现MUL指令

时间:2017-10-27 14:32:54

标签: assembly x86-16 cpu-registers multiplying

我需要乘以数字,但不使用Assembly 8086中的MUL指令。

例如:

mov bx, 2
bx -> bx * 41; code instead this line

任何帮助?

2 个答案:

答案 0 :(得分:1)

一个简单的解决方案是使用重复添加。

使用其中一个数字作为计数器,add使用其他数字作为结果的许多倍。

这里重要的是,结果需要标注为两倍原始数字的大小。如果两个数字都是16位,则结果必须是32位。

接下来最好使用两个数字中最小的数字作为计数器。这将减少迭代次数。

如果计数器为零,也不要忘记启动循环。那么产品显然是零。

 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:

此处的产品位于DX:AX

答案 1 :(得分:0)

要将变量乘以常数,可以在方便的时候将常数分解为2的幂;例如,AX = AX * 320,320 = 2 ^ 8 + 2 ^ 6。 然后为每个幂和一个总和向变量的左侧移动。 AX = AX * 320变为:AX = AX&lt;&lt; 8 + AX&lt;&lt;但是,AX <&lt; 6&lt; 8 =(AX <&lt; 6)&lt;&lt; 2。 如果要乘以负常数,可以应用相同的方法,但必须先取消输入。

正如Fifoernik所说,如果你想将一个16位寄存器乘以一个常数,你可能需要最多32位的结果(此外你可以有负输入数);我编写的所有例程都经过成功测试,比IMUL(Peter Norton的8086汇编指南)快三倍:

示例A;将AX乘以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;

实施例B;将AX乘以-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;

实施例1B;将AX乘以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;

实施例2B;将AX乘以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;

实施例3B;将AX乘以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;

如果您不需要32位结果(仅适用于正数):

实施例1;将AX乘以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)}

例2;将AX乘以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)}

实施例3;将AX乘以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)}