本文介绍了可变位移的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望将一个寄存器位向左移动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.

这篇关于可变位移的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-14 09:07