【问题标题】:Assembly language using shl to multiply by an odd number?使用 shl 乘以奇数的汇编语言?
【发布时间】:2013-11-22 17:16:43
【问题描述】:

我需要将 EAX 乘以 37,我知道我可以使用 shl eax,5shl register,2 然后将寄存器添加到 eax 以乘以 38,但我不确定乘以奇数的代码,我只能使用 shl add 和 mov。谢谢!

【问题讨论】:

  • 也加上原版(未移位)eax
  • 哇,这么简单,非常感谢,我应该知道这样做哈哈。
  • 如果您想在回复中发布该内容,我很乐意为此给您 +1!

标签: assembly x86


【解决方案1】:

使用 LEA,您可以直接乘以许多小的奇数常数 (2,4,8,3,5,9),以及将两个寄存器相加并将答案移动到不同的位置。这非常有用。组合这些,您可以使用一系列 LEA 指令乘以几乎任何小常数,通常很短。明智地使用其他 ADD、SHL 和 SUB(包括 NEG 然后 ADD)指令可以缩短这些序列。如此短的序列几乎总是比使用乘法更快,部分原因是当前处理器在执行时会重叠许多指令:

将 eax 乘以 37:

 lea ecx, [eax+8*eax] ; 9 * eax
 lea eax, [ecx*4+eax] ; 37 * eax

将 eax 乘以 38:

 lea ecx, [8*eax]
 neg eax
 lea ecx, [5*ecx] 
 lea eax, [ecx+2*eax]

更好:

 lea ecx, [8*eax+eax] ; 9 * eax
 lea ecx, [4*ecx] ; 36 * eax
 lea eax, [eax*2+ecx] ; 38 * eax

只是为了好玩,乘以 103:

 lea ecx, [8*eax] ; 8 * eax
 lea ecx, [ecx*4] ; 32 * eax
 lea ecx, [ecx*2+ecx] ; 96 * eax
 lea ecx, [ecx+8*eax]; ; 104 * eax
 sub ecx, eax ; 103 * eax

【讨论】:

    【解决方案2】:

    除了 harold 告诉您的内容之外,您还可以使用 LEA 指令来执行乘法运算:

    EAX * 2 :  lea eax,[eax*2]
    EAX * 3 :  lea eax,[eax*2+eax]
    EAX * 4 :  lea eax,[eax*4]
    EAX * 5 :  lea eax,[eax*4+eax]
    EAX * 8 :  lea eax,[eax*8]
    EAX * 9 :  lea eax,[eax*8+eax]
    

    【讨论】:

    • 对于就地乘以 2 的幂,使用 shl eax, 3 而不是 lea[eax*8] 寻址模式可能需要在编码中使用 32 位 0 位移,因为编码没有基址寄存器的缩放索引的唯一方法是使用 disp32。另外,eax*2 最好使用add eax,eax,它可以在比lea 更多的端口上运行。
    猜你喜欢
    • 2016-02-06
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 1970-01-01
    • 2020-07-24
    相关资源
    最近更新 更多