X86 Assembly/Shift and Rotate

Logical Shift Instructions
In a logical shift instruction (also referred to as unsigned shift), the bits that slide off the end disappear (except for the last, which goes into the carry flag), and the spaces are always filled with zeros. Logical shifts are best used with unsigned numbers.

Logical shift  to the right by   bits.

Logical shift  to the left by   bits.

Examples (GAS Syntax):

Arithmetic Shift Instructions
In an arithmetic shift (also referred to as signed shift), like a logical shift, the bits that slide off the end disappear (except for the last, which goes into the carry flag). But in an arithmetic shift, the spaces are filled in such a way to preserve the sign of the number being slid. For this reason, arithmetic shifts are better suited for signed numbers in two's complement format.

Arithmetic shift  to the right by   bits. Spaces are filled with sign bit (to maintain sign of original value), which is the original highest bit.

Arithmetic shift  to the left by   bits. The bottom bits do not affect the sign, so the bottom bits are filled with zeros. This instruction is synonymous with SHL.

Examples (GAS Syntax):

Extended Shift Instructions
The names of the double precision shift operations are somewhat misleading, hence they are listed as extended shift instructions on this page.

They are available for use with 16- and 32-bit data entities (registers/memory locations). The  operand is always a register, the   operand can be a register or memory location, the   operand is an immediate byte value or the CL register. In 64-bit mode it is possible to address 64-bit data as well.

The operation performed by  is to shift the most significant   bits out of , but instead of filling up the least significant bits with zeros, they are filled with the most significant   bits of.

Likewise, the  operation shifts the least significant   bits out of , and fills up the most significant   bits with the least significant bits of the   operand.

Intel's nomenclature is misleading, in that the shift does not operate on double the basic operand size (i.e. specifying 32-bit operands doesn't make it a 64-bit shift): the  operand always remains unchanged.

Also, Intel's manual states that the results are undefined when  is greater than the operand size, but at least for 32- and 64-bit data sizes it has been observed that shift operations are performed by, with n being the data size.

Examples (GAS Syntax):

Other examples (decimal numbers are used instead of binary number to explain the concept)

Rotate Right
In a rotate instruction, the bits that slide off the end of the register are fed back into the spaces.

Rotate to the right by  bits. Here is a graphical representation how this looks like: ╭─────────────────╮ %al old     │ 0 0 1 0'0 1 1 1 │ ror 1, %al ╰─╮╲ ╲ ╲ ╲ ╲ ╲ ╲╰─╯ %al new       1 0 0 1'0 0 1 1 The number of bits to rotate is masked to the lower 5 bits (or 6 bits in 64-bit mode). This is equivalent to a $$\text{offset}\!\!\!\!\mod 32$$ operation, i.&#8239;e. the remainder of integer division (note: $$2^5 = 32$$). This means, you can never do one or more “complete” rotations.

Operands

 * has to be a register or memory location.
 * can be either
 * an immediate value (where the value  has a dedicated opcode),
 * or the  register (that is the lowest byte of  ).

Modified Flags
only alters flags if the masked is non-zero. The CF becomes the most recently rotated bit, so in the case of  the result ’s MSB (the “sign”).

Furthermore, if the masked  = 1, OF  ≔  result [MSB] ⊻  result [MSB−1], so the OF tells us, whether “the sign” has changed.

Rotate Left
Rotate to the left by  bits.

Operands and modified flags are pretty much the same as for. However, in the case that the masked  = 1, the OF is defined differently, although it has effectively same meaning. For  the OF  ≔  result [MSB] ⊻  result [LSB].

Note that the CF contains the LSB in the case of.

Rotate With Carry Instructions
Like with shifts, the rotate can use the carry bit as the "extra" bit that it shifts through.

Rotate  to the right by   bits with carry.

Rotate  to the left by   bits with carry.

Number of arguments
Unless stated, these instructions can take either one or two arguments. If only one is supplied, it is assumed to be a register or memory location and the number of bits to shift/rotate is one (this may be dependent on the assembler in use, however). is equivalent to   (GAS syntax).