Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

assembly - Variable bit shift

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...