1.5. Shifts

The shift instructions shift all the bits in a register to by a given amount. However, unlike with rotate, when bits move past position 0 or 31, they disappear. Shifting this pattern:

313029282726252423222120191817161514131211109876543210
00000000000000000000101010110000
00000AB0

8 bits to the right would end up “dropping” the 8 rightmost bits:

313029282726252423222120191817161514131211109876543210
00000000000000000000000000001010
0000000A

Since the bits do not wrap, we can’t fake a left shift with a right one.

LSLrd, rn, rm / #

Logical Shift Left. Shift rn to the left the number of bits in rm or #. Result in rd.

LSRrd, rn, rm / #

Logical Shift Right. Shift rn to the right the number of bits in rm or #. Result in rd.

MOV  r1, #0x12     @ r1 = 0000 ... 0000 0001 0010

@Shift 4 BITS or 1 hex digit to the right
LSL  r2, r1, #4    @ r2 = 0000 ... 0001 0010 0000

@Shift 2 BITS to the left
LSR  r3, r1, #2    @ r3 = 0000 ... 0000 0000 0100

@Shift r1 by number of bits in r3 (4), result in r5
LSL   r5, r1, r3
Try sample

1.5.1. Multiplying and Dividing via Shift

Shifting bits that represent a binary number to the left one place is equivalent to multiplying it by 2. Here, binary for 5 gets shifted and becomes 10 (A):

313029282726252423222120191817161514131211109876543210
00000000000000000000000000000101
00000005
313029282726252423222120191817161514131211109876543210
00000000000000000000000000001010
0000000A

Shifting 2 bits is equivalent to multiplying by 4. Each additional bit shifted represents an additional power of 2.

MOV   r1, #5
LSL   r2, r1, #1  @ r6 = 10 or 0xA
LSL   r3, r1, #2  @ r6 = 20 or 0x14
LSL   r4, r1, #8  @ r6 = 5 * 256 = 1280 or 0x500
Try sample

Conversely, each bit shifted to the right divides a binary pattern by 2. Here is 24 (0x18) shifted right to produce 12 (0xC):

313029282726252423222120191817161514131211109876543210
00000000000000000000000000011000
00000018
313029282726252423222120191817161514131211109876543210
00000000000000000000000000001100
0000000C

However, when we shift to the right, and the pattern represents a two’s complement value, shifting in a 0 for the leftmost bit can cause an error. Watch what happens if we shift -2 (0xFFFFFFFE) to the right one bit - we get 0x7FFFFFFF or 2,147,483,647‬:

313029282726252423222120191817161514131211109876543210
11111111111111111111111111111110
FFFFFFFE
313029282726252423222120191817161514131211109876543210
01111111111111111111111111111111
7FFFFFFF

To get the right answer, we need to copy the leftmost bit as we shift the pattern. Here is a correct version of -2 / 2 to produce -1 (0xFFFFFFFF):

313029282726252423222120191817161514131211109876543210
11111111111111111111111111111110
FFFFFFFE
313029282726252423222120191817161514131211109876543210
11111111111111111111111111111111
FFFFFFFF

This is the point of the Arithmetic Shift Right instruction - it does a shift that preserves the sign of a two’s complement number:

ASRrd, rn, rm / #

Arithmetic Shift Right. Shift rn to the right the number of bits in rm or #, copying the leftmost bit to fill the void. Result in rd.

MOV   r5, #50
ASR   r6, r5, #1     @ r6 = r5 / 2
ASR   r7, r5, #3     @ r7 = r5 / 8
MOV   r8, #-200
ASR   r9, r8, #6     @ r9 = r8 / 64 = 3
Try sample

Tip

Shifting n bits to the left multiplies a value by 2^n. Shifting to the right divides by 2^n as long as you preserve the leftmost bit.

You have attempted of activities on this page
Next Section - 1.6. Operand Shifts