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. |
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:
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.