繁体   English   中英

在不使用指令MUL,IMUL,SHL,SHR,LOOP的情况下将数字相乘

[英]Multiply numbers without using instructions MUL, IMUL, SHL, SHR, LOOP

是否可以不使用x86汇编语言中的指令MUL,IMUL,SHL,SHR,LOOP,JMP来计算乘法结果?

以下代码将寄存器ecxedx的内容相乘,并将结果存储在寄存器eax 寄存器ebxedx被破坏:

  mov ebx, 1
  mov eax, 0
repeat:
  test ecx, ebx
  jz dontadd
  add eax, edx
dontadd:
  add edx, edx
  add ebx, ebx
  jnz repeat

没有...循环

如果“ LOOP”不仅涵盖“ LOOP”指令,还包括任何条件跳转指令:

在没有条件跳转指令的情况下进行乘法要困难一些,但并非没有可能。 下面的示例这样做(输入: ecxedx ,输出eax ,使用的所有寄存器的内容都会被破坏):

mov ebx, 1
mov eax, 0
not ecx
  # Repeat the following code 32 times:
mov esi, ebx
and esi, ecx
dec esi
and esi, edx
add eax, esi
add edx, edx
add ebx, ebx
  # (repeat the code here)

是否可以不使用x86汇编语言中的指令MUL,IMUL,SHL,SHR,LOOP,JMP来计算乘法结果?

是。

如果没有MUL,通常的方法是循环循环“ SHIFT LEFT,TEST和ADD”,如下所示:

    result = 0;
    while(a > 0) {
        result = result << 1;
        if( a & 0x80000000 != 0) {
            result = result + b;
        }
        a = a << 1;
    }

请注意,像这样的32位整数循环最多(最多)进行32次迭代。

您可以将这些班次替换为shl eax, 1 (例如shl eax, 1替换为add eax, eax ); 您可以将LOOP替换为显式循环(例如dec ecxjne next )或展开循环(重复32次代码)。 这些替换可能会提高性能。

一旦完成无符号乘法运算,就可以将IMUL替换为将值转换为正数并使用无符号乘法运算的分支。 例如:

    if(a < 0) {
        a = -a;
        if(b < 0) {
            b = -b
            return a*b;    // Unsigned multiplication
        } else {
            return -a*b;   // Unsigned multiplication
        }
    } else {
        if(b < 0) {
            b = -b
            return -a*b;   // Unsigned multiplication
        } else {
            return a*b;    // Unsigned multiplication
    }
}

反对全表查找对数,加法和求幂的地狱,您仍然可以
平方和减法的表查找 :ab = (a + b)²/ 4-(ab)²/ 4

没有乘法指令的CPU通常可以通过重复加法来执行此操作,但是如果没有循环,这将变得极为困难。

但是,由于您尚未指定感兴趣的特定 CPU,因此我假定其中一个具有以下指令:

add rt, rs, count

rs加到rt指令精确count时间。 这将使您无需loopjump指令即可执行此操作:-)

当然,你可能只是有一个paxmul指令,可以做乘法你-技术上不是mul ,但对这个问题的精神无疑。

但是,老实说,由于您实际上很难在没有列出的指令的情况下尝试找到CPU,因此这个问题可能被认为是没有实际意义的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM