Section 04 Part 06 – The LSL, LSR, ASL & ASR Instructions “We live in a world of shifting values. The family is falling apart. Parents failing in what they ought to do.” ~Gordon B. Hinckley

Introduction

In the previous part we looked at “bit shifting”, and how it works for both logical and arithmetic shifting.  In this part, we look at several instructions that deal with shifting in some form.  And since they have more or less the same mnemonic rules, it makes sense to keep them all in one section.

If any of you have a hard time following this section, then feel free to drop me a line, and I’ll see what I can do to improve it.

My email address can be found on the Main Page.

The LSL Instruction

LSL – Logical Shift Left

This instruction will shift the bits of the destination operand to the left.  The number of times that the bits are shifted is decided by the source operand.

Examples

We’ll start with the standard example I always use:

 lsl.b     #\$02,d0

This will shift the byte of d0, 02 bits to the left.  Now, we’ll pretend that d0 contains 000004B2 in this example, and since it’s a byte, only the B2 is change.  B2 in binary is:

 1011 0010

After shifting the bits left by 02, we get:

 < 1100 1000 <

1100 1000 in hex is C8, which is saved back into d0.  Now d0 contains 000004C8.

Here’s another example:

 lsl.w     #\$04,d2

This will shift the word of d2, 04 bits to the left.  We’ll pretend that d2 contains 00F0FEDC, and since it’s a word size, only the FEDC is changed.  FEDC in binary is:

 1111 1110 1101 1100

Shifting left 04 bits results in:

 < 1110 1101 1100 0000 <

FEDC has changed to EDC0.  Now d2 contains 00F0EDC0.

Shift size and syntax

These rules apply to the LSL, LSR, ASL, ASR, ROL and ROR instructions, which are coming next, so please pay attention.

Immediate shifting

Now the maximum shift size you can perform in one instruction is 08 bits, while the minimum is 01 bit.  If you’re looking to shift any higher than 08 bits, then there’s nothing stopping you from using the same instruction twice.  For example, shifting left by 0C:

 lsl.l     #\$08,d0           lsl.l     #\$04,d0

Above, you can see the first instruction will shift left by 08 bits, while the second instruction will shift left by an extra 04 bits making the 0C shift size.  There are of course, other (quicker) methods, but they’re better left for another time.

Now if you wanted to shift left by only 01 bit, you can in fact, write the instruction out like so:

 lsl.w     d0

When the assembler assembles that instruction, it will convert it to this:

 lsl.w     #\$01,d0

Some people prefer not to put in the #\$01, probably to save themselves some typing time, who knows.  I always put the value in personally.  Whichever way you want to do it is absolutely fine and will have no effect on the final result, they are exactly the same.

Data register shifting

You can shift using one data register as a shift size, for example:

 lsl.l     d0,d1

Now in this example, d1 is shifted left by the number held in d0.  We’ll pretend at d0 contains 0000010F.

For the source operand, only a byte is read as the shift count.  Since d0 contains 0000010F, only the 0F is used.  So, the long-word of d1 is shifted left by 0F bits.

The maximum number of bits you can shift by depends on the size you chose:

• .b for byte gives a maximum shift of \$08 bits.
• .w for word gives a maximum shift of \$10 bits.
• .l for long-word gives a maximum shift of \$1F bits.

The instruction will automatically shift at the maximum size, if the source operand’s byte is higher than the maximum.  For example:

 lsl.b     d0,d1

The size is .b for byte, so if d0 contains a byte that’s 09 or higher, then the maximum number of times d1 will shift over is automatically 08.

Memory shifting

When using the shift instructions on data registers, you have the freedom to use, byte, word or long-word sizes.  And you can shift more than 01 bit at a time.  For memory though, you can only use word, and can only shift 01 bit at a time:

 lsl.w     \$00FF0000           lsl.w     \$20(a0)           lsl.w     (a0)+           lsl.w     -(a0)

Notice in the memory examples above, there is no source operand, if you were to write them as:

 lsl.w     #\$01,\$00FF0000           lsl.w     #\$01,\$20(a0)           lsl.w     #\$01, (a0)+           lsl.w     #\$01,-(a0)

Your assembler may notify you with an error.  Some assemblers might not be as picky, but it’s best that you do not specify the size 01 for shifting data in memory.

You cannot perform this instruction directly on address registers in any way:

 lsl.w     #\$04,a0           lsl.l     a0           lsl.l     d0,a0

The LSR Instruction

LSR – Logical Shift Right

This instruction will shift the bits of the destination operand to the right.  The number of times that the bits are shifted is decided by the source operand.

Examples

 lsr.b     #\$02,d0

This will shift the byte of d0, 02 bits to the right.  We’ll pretend that d0 contains 000004B2 in this example, and since it’s a byte, only the B2 is change.  B2 in binary is:

 1011 0010

After shifting the bits right by 02, we get:

 > 0010 1100 >

0010 1100 in hex is 2C, which is saved back into d0.  Now d0 contains 0000042C.

Here’s another example:

 lsr.w     #\$04,d2

This will shift the word of d2, 04 bits to the right.  We’ll pretend that d2 contains 00F0FEDC, and since it’s a word size, only the FEDC is changed.  FEDC in binary is:

 1111 1110 1101 1100

Shifting right 04 bits results in:

 > 0000 1111 1110 1101 >

FEDC has changed to 0FED.  Now d2 contains 00F00FED.

The ASL Instruction

ASL – Arithmetic Shift Left

This instruction will shift the bits of the destination operand to the left arithmetically.  The number of times that the bits are shifted is decided by the source operand.

Examples

This is pretty much the same as using the LSL instruction:

 asl.b     #\$02,d0

This will shift the byte of d0, 02 bits to the left.  Now, we’ll pretend that d0 contains 000004B2 in this example, and since it’s a byte, only the B2 is change.  B2 in binary is:

 1011 0010

After shifting the bits left by 02, we get:

 < 1100 1000 <

1100 1000 in hex is C8, which is saved back into d0.  Now d0 contains 000004C8.

Since shifting left logical and arithmetic are the same, this instruction behaves the same way as the LSL instruction.

There is one difference however, in that LSL will clear the V flag while ASL will clear or set the V flag based on the outcome.  However, the V flag is part of the CCR, and that will be explained later on during the tutorial with a quick reference manual you can look up on.  So don’t worry about it for now.

The ASR Instruction

ASR – Arithmetic Shift Right

This instruction will shift the bits of the destination operand to the right arithmetically.  The number of times that the bits are shifted is decided by the source operand.

Examples

 asr.b     #\$02,d0

This will shift the byte of d0, 02 bits to the right.  We’ll pretend that d0 contains 000004B2 in this example, and since it’s a byte, only the B2 is change.  B2 in binary is:

 1011 0010

After shifting the bits right by 02, we get:

 > 1110 1100 >

1110 1100 in hex is EC, which is saved back into d0.  Now d0 contains 000004EC.

Please note, the MSB was 1 before, so it stays as 1.

Here’s another example:

 asr.w     #\$04,d2

This will shift the word of d2, 04 bits to the right.  We’ll pretend that d2 contains 00F07EDC, and since it’s a word size, only the 7EDC is changed.  7EDC in binary is:

 0111 1110 1101 1100

Shifting right 04 bits results in:

 > 0000 0111 1110 1101 >

7EDC has changed to 07ED.  Now d2 contains 00F007ED.

The MSB was 0 before, so it stays as 0.