我希望将一个寄存器位向左移动 n 次,用另一个寄存器指定。例如,像这样
shl eax, ebx
唯一的问题是第二个操作数不能是寄存器,它必须是立即数。我如何能够将寄存器移位一个在汇编时未知的值?
我希望将一个寄存器位向左移动 n 次,用另一个寄存器指定。例如,像这样
shl eax, ebx
唯一的问题是第二个操作数不能是寄存器,它必须是立即数。我如何能够将寄存器移位一个在汇编时未知的值?
在 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 上可用,因此您不能在完全可移植的代码中使用它。