In x86 you can specify a shift count in register cl
. So shl eax, cl
is valid.
mov ecx, ebx
shl eax, cl
Note that you can only use the cl
register, not eax
or any other register.
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
).
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)
It's only available on some Haswell+ CPUs, and Excavator / Ryzen CPUs, so you can't use it in fully portable code.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…