4

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?

3
  • Are you writing inline assembly in C/C++ ? Commented Nov 16, 2012 at 22:29
  • No, otherwise I would've just used the shift operators. Commented Nov 16, 2012 at 22:31
  • 2
    You should read the instruction set reference. Commented Nov 16, 2012 at 23:22

1 Answer 1

17

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.