试图通过 EAX 左移一个变量
Posted
技术标签:
【中文标题】试图通过 EAX 左移一个变量【英文标题】:Trying to shift left by EAX a variable 【发布时间】:2017-07-08 16:03:39 【问题描述】:如何使用命令shl
将变量移1?
mov one, 1
shl one , eax
返回错误。
【问题讨论】:
【参考方案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 向左移动,因此还有一条适用的指令:bts
。 bts
可以将任何寄存器作为索引。
xor edx, edx
bts edx, eax
将它与内存目标一起使用时要小心,索引不会以 32 为模减少,因此您可以使用它来(不小心)将其设置为远离基地址。
【讨论】:
memory-destinationbts
通常比使用 xor + bts edx, eax
创建掩码要慢,然后使用 or [mem], edx
。正是因为这种疯狂的 CISC 行为将源寄存器视为位字符串的索引,所以它解码为很多微指令。以上是关于试图通过 EAX 左移一个变量的主要内容,如果未能解决你的问题,请参考以下文章