Bit shifting operations
Last updated
Last updated
"Bit shifting" is a bitwise operation in which you move bits left or right. As a result, practically speaking, you divide or multiply a number by two.
There are two opcodes which shift bits to the left or right.
ASL and LSR can affect either A or an address, just like INC and DEC. Here's an example of ASL in action:
This is what appears on the surface. When you look at the numbers in binary though, this is what it looks like:
As you can see, the digit "1" has moved to the left once. That is what ASL does, moving bits left.
ASL can also move bits in an address without affecting A.
You can also shift bits to the right by using LSR.
And when you look at it on the level of binary, rather than hexadecimal:
As you can see, the digit "1" has moved to the right once. That is what LSR does, moving bits right.
LSR can also move bits in an address without affecting A.
You might be wondering what happens if you bit shift %1000 0001
to the right once, by using LSR. Bit 7 is currently set, but there's nothing to shift into bit 7. At the same time, bit 0 is also set, but it has nowhere to shift into. When this happens, bit 0 will move into the carry flag. At the same time, bit 7 will be set to 0.
The opposite is also true when you shift %1000 0001
to the left once, by using ASL. Bit 7 will move into the carry flag, while bit 0 will be set to 0.
Here are some examples of a bit moving into the carry flag.
By chaining ASL and LSR, you can multiply or divide a value by 2 several times, therefore multiplying or dividing it by 2, 4, 8, 16, and so on. It's 2ⁿ, where n is the amount of ASL or LSR instructions you're chaining.
Here's an example of multiplying a value by 8.
Here's an example of dividing a value by 4
There are two opcodes which rotate bits to the left or right, rather than shifting.
They behave the same as LSR and ASL, except they are using the carry flag as an extra bit in order to make the bits "wrap" around. This means that the value can't be "stuck" at $00 eventually, like it happens in ASL and LSR. This is why they're called rotate, rather than shift.
Here's an example of ROL:
As you can see, bit 7 wrapped all the way around to bit 0, basically "rotating" the bits without losing any information.
As you can see, bit 0 wrapped all the way around to bit 7, basically "rotating" the bits without losing any information.
As you can see, you can set the carry flag and rotate. This will result in A being modified anyway, even though A started out as $00.
Rotation can also affect addresses, just like ASL and LSR. Here's an example:
All the previous explanations and behaviours apply to 16-bit bit shifting as well. It's just that you're working with 16 bits and the carry flag, not 8 bits.
Opcode
Full name
Explanation
ASL
A or memory shift left
Moves bits left once without carry, practically multiplying a value by 2
LSR
A or memory shift right
Moves bits right once without carry, practically dividing a value by 2
Opcode
Full name
Explanation
ROL
Rotate A or memory left
Moves bits left once with carry, wrapping the bits around
ROR
Rotate A or memory right
Moves bits right once with carry, wrapping the bits around