3

我希望将一个寄存器位向左移动 n 次,用另一个寄存器指定。例如,像这样

shl    eax, ebx

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

4

1 回答 1

15

在 x86 中,您可以在 register 中指定移位计数cl。所以shl eax, cl是有效的。

mov   ecx, ebx
shl   eax, cl

请注意,您只能使用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)

它仅在某些 Haswell+ CPU 和 Excavator / Ryzen CPU 上可用,因此您不能在完全可移植的代码中使用它。

于 2012-11-16T22:31:25.277 回答