A logical shift moves bits to the left or right. The bits which 'fall off' the end of the word are discarded and the word is filled with 0's from the opposite end. A logical right shift of the 8 bit binary number 1000 1011 gives 0100 0101, as shown below:
Shift instructions include a repeat value, which is the number of times the single bit shift operation is repeated.
A rotate operation is a circular shift in which no bits are discarded. A rotate right of the 8 bit binary number 1000 1011 gives 1100 0101, as shown below.
A right rotation by n bits of an n bit word returns the original word unchanged. A right rotation by n-1 bits is equivalent to a left rotation of 1 bit. The left rotation instruction is redundant because a left rotation of j bits is equivalent to a right rotation of n-j bits.
On positive integers, a logical left shift is equivalent to multiplication by 2 and a logical right shift is equivalent to division by 2. The arithmetic shift extends this operation to negative 2's complement integers.
An arithmetic right shift is similar to a logical right shift, except that the leftmost bits are filled with the sign bit of the original number instead of 0's.
An arithmetic right shift of the 8 bit number 1000 1011 gives 1100 0101, as shown below:
Observe that in 8 bit 2's complement 1000 1011 equals decimal -117 and the result after the arithmetic right shift is 1100 0101, which equals decimal -59.
The SAL shift instructions are:
There are no Pascal operations equivalent to these shift operations.
Shift operations may be combined with logical operations to extract and align bit fields. For example, the exponent of an IEEE floating point number, F, may be extracted as follows:
and E, F, 0x7F800000 # mask the exponent field srl E, E, 23 # shift exponent to the right sub E, E, 127 # convert from biased-127
In this example, E and F are both words.
Values in memory may be converted to hexadecimal using mask and shift operations. For example, the leftmost hexadecimal digit in a word, I, may be printed as follows:
.data I: .word # the number to be printed T: .word # temporary to hold hex digit C: .byte # hex digit in ASCII .text __start: get I # read a number and T, I, 0xF0000000 # mask leftmost hex digit rol T, T, 4 # rotate to bits 0-3 move C, T # truncate to byte add C, C, '0' # convert to ASCII ble C, '9', print # check for A-F add C, C, 7 # convert A-F to ASCII print: put C # print hex digit done
By adding a loop which rotates I by 4 bits to the left on each iteration, an entire word may be printed in hexadecimal form.