【问题标题】:Trying to shift left by EAX a variable试图通过 EAX 左移一个变量
【发布时间】:2017-07-08 16:03:39
【问题描述】:

如何使用命令shl 将变量移1?

mov one, 1

shl one , eax 

返回错误。

【问题讨论】:

    标签: assembly x86 bit-shift


    【解决方案1】:

    唯一进行可变数量移位的方法是将移位计数放入CL 寄存器(这是 32 位 ECX 寄存器的低 8 位)。这是the only encoding available for any of the shift instructions that takes a register source operand

    所以你需要这样做:

    mov DWORD PTR [one], 1      ; initialize variable 'one'
    mov ecx, eax                ; copy shift count from EAX into ECX
    shl DWORD PTR [one], cl     ; one << cl
    

    请注意,这里只使用了ECX 的低 8 位,但这已经足够了,因为无论如何您不能将 DWORD 大小的值移动超过 32 位!事实上,在除 8088/8086 之外的所有设备上,移位计数都将被屏蔽为 5 位(即模 32),将其限制在 0-31 的范围内,包括 0-31。

    另外,我应该提一下,虽然您可以使用内存操作数作为像移位这样的算术指令的来源,但您可能不应该因为它比使用一个寄存器。所以,既然你必须破坏一个寄存器,你可以这样做:

    mov  ecx, eax
    mov  eax, 1
    shl  eax, cl
    mov  DWORD PTR [one], eax
    

    【讨论】:

      【解决方案2】:

      除非您使用BMI2 shifts,否则您只能移位cl。比如:

      mov edx, 1
      shl edx, cl
      

      由于您将值 1 向左移动,因此还有一条适用的指令:btsbts 可以将任何寄存器作为索引。

      xor edx, edx
      bts edx, eax
      

      将它与内存目标一起使用时要小心,索引不会以 32 为模减少,因此您可以使用它来(不小心)将其设置为远离基地址。

      【讨论】:

      • memory-destination bts 通常比使用 xor + bts edx, eax 创建掩码要慢,然后使用 or [mem], edx。正是因为这种疯狂的 CISC 行为将源寄存器视为位字符串的索引,所以它解码为很多微指令。
      猜你喜欢
      • 2017-07-20
      • 1970-01-01
      • 1970-01-01
      • 2017-01-03
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 2021-06-27
      • 2012-10-15
      相关资源
      最近更新 更多