可变位移

123*_*123 2 x86 assembly bit-manipulation

我希望将寄存器位移位n次到另一个寄存器指定的左侧.例如,像这样的东西

shl    eax, ebx
Run Code Online (Sandbox Code Playgroud)

唯一的问题是第二个操作数不能是一个寄存器,它必须是一个立即值.如何将寄存器移位到汇编时未知的值?

Geo*_*aál 12

在x86中,您可以在寄存器中指定移位计数cl.所以shl eax, cl是有效的.

mov   ecx, ebx
shl   eax, cl
Run Code Online (Sandbox Code Playgroud)

请注意,您只能使用cl寄存器,不能使用eax任何其他寄存器.

此外,大于31的移位计数以模32执行.(不以操作数大小为模,因此窄移位shl ax, 20 可以将所有位移出并使目标保持为零.但是,64位移位会掩盖计数& 63,但是,shl rax, 32(或者)有可能是32 in cl.请参阅英特尔的手册条目shl).


BMI2指令集扩展支持在任何寄存器中具有计数的移位,并且不更新EFLAGS,因此它们对于变量计数更有效:

; if BMI2 is supported
shlx   edx, eax, ebx     ; edx = eax << (ebx&31)
Run Code Online (Sandbox Code Playgroud)

它仅适用于一些Haswell + CPU和Excavator/Ryzen CPU,因此您无法在完全可移植的代码中使用它.