问题描述
我希望将一个寄存器位向左移动n次(由另一个寄存器指定).例如,类似这样的
I'm looking to shift a register bits n times to the left specified with another register. For example, something like this
shl eax, ebx
唯一的问题是第二个操作数不能是寄存器,它必须是立即数.我如何才能将寄存器移位汇编时未知的值?
The only problem being is that the 2nd operand cannot be a register, it has to be an immediate value. How would I be able to shift a register by a value not known at assemble-time?
推荐答案
在x86中,您可以在寄存器cl
中指定移位计数.所以shl eax, cl
是有效的.
In x86 you can specify a shift count in register cl
. So shl eax, cl
is valid.
mov ecx, ebx
shl eax, cl
请注意,您只能使用cl
寄存器,不能使用eax
或任何其他寄存器.
Note that you can only use the cl
register, not eax
or any other register.
此外,以32为模执行大于31的移位计数.(不是以操作数大小为模,因此像shl ax, 20
这样的窄移位可以将所有位移出并保留目标零.64但是,通过位移位可以用& 63
掩盖计数,因此可以使用shl rax, 32
(或在cl中包含32). .html"rel =" nofollow noreferrer> shl
的英特尔手册条目.
Also, shift counts greater than 31 are performed modulo 32. (Not modulo the operand-size, so narrow shifts like shl ax, 20
can shift all the bits out and leave the destination zero. 64-bit shifts mask the count with & 63
, though, so shl rax, 32
(or with 32 in cl) is possible. See Intel's manual entry for shl
).
BMI2指令集扩展支持根据任何寄存器中的计数进行移位 ,并且不会更新EFLAGS,因此它们对于可变计数更为有效:
The BMI2 instruction set extension supports shifts with the count in any register, and which don't update EFLAGS, so they're more efficient for variable counts:
; if BMI2 is supported
shlx edx, eax, ebx ; edx = eax << (ebx&31)
仅在某些Haswell + CPU和Excavator/Ryzen CPU上可用,因此您不能在完全可移植的代码中使用它.
It's only available on some Haswell+ CPUs, and Excavator / Ryzen CPUs, so you can't use it in fully portable code.
这篇关于可变位移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!