Rotate Bits
The rotate instructions shifts the contents of the accumulator or memory location one bit either to the left or right.
The ROL & ROR instructions will shift in the carry flag into the value. The ASL & LSR instructions shift in 0. The carry flag is set to the bit that was shifted out of the value.
On all processors the data shifted is 8 bits.
On the 65816 with m=0, the data shifted is 16 bits.
Operation | Opcode | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
---|---|---|---|---|---|---|---|---|---|---|---|
Shift left | ASL | C | 0 | ||||||||
Shift left with carry | ROL | C | C | ||||||||
Shift right | LSR | 0 | C | ||||||||
Shift right with carry | ROR | C | C |
ASL - Shift Memory or Accumulator Left
Shift the value left one bit. The left most bit is transferred into the carry flag. The right most bit is cleared.
The arithmetic result of the operation is an unsigned multiplication by two.
LSR - Logical Shift Memory or Accumulator Right
Shift the value right one bit. The right most bit is transferred into the carry flag. The left most bit is cleared.
The arithmetic result of the operation is an unsigned division by two.
ROL - Rotate Memory or Accumulator Left
Shift the value left one bit. The right most bit is set to the initial value of the carry flag. The left most bit is transferred into the carry flag.
ROR - Rotate Memory or Accumulator Right
Shift the value right one bit. The left most bit is set to the initial value of the carry flag. The right most bit is transferred into the carry flag.
Multi-word shifts
These instructions can be combined to handle multiple word values:
Multi-word shift left
To shift left multiple words, use ASL for the first operation then ROL for the subsequent words.
1 ; Shift 16-bit value at &70 left 1 bit.
2 ; This is effectively a multiplication by 2
3 ASL &70 ; Shift left low-order byte
4 ROL &71 ; Shift left high-order byte
5 ; Carry will be set if we overflowed
6
For higher precision simply add an additional ROL for the next order byte.
Multi-word shift right
To shift right multiple words, use LSR for the first operation then ROR for the subsequent words. Unlike shifting left, here we have to start with the high-order byte first.
1 ; Shift 16-bit value at &70 right 1 bit.
2 ; This is effectively a division by 2
3 LSR &71 ; Shift right high-order byte
4 ROR &70 ; Shift right low-order byte
5 ; Carry will have the remainder
6
For higher precision just start the LSR on the higher order byte & use ROL for each lower order.
Flags Affected
Flags |
| ||||||||
---|---|---|---|---|---|---|---|---|---|
n | Set if the most significant bit of the result is set | ||||||||
z | Set if the result is zero | ||||||||
c | The value of the bit shifted out of the result |
Instructions
Syntax | Opcode | Available on: | # of | # of | Addressing Mode | ||
---|---|---|---|---|---|---|---|
(hex) | 6502 | 65C02 | 65816 | bytes | cycles | ||
ASL A | 0A | x | x | x | 1 | 2 | Accumulator |
ASL addr | 0E | x | x | x | 3 | 6 | Absolute |
ASL dp | 06 | x | x | x | 2 | 51, 2 | Direct Page |
ASL addr,X | 1E | x | x | x | 3 | 71, 3 | Absolute Indexed X |
ASL dp,X | 16 | x | x | x | 2 | 61, 2 | Direct Page Indexed X |
LSR A | 4A | x | x | x | 1 | 2 | Accumulator |
LSR addr | 4E | x | x | x | 3 | 6 | Absolute |
LSR dp | 46 | x | x | x | 2 | 51, 2 | Direct Page |
LSR addr,X | 5E | x | x | x | 3 | 71, 3 | Absolute Indexed X |
LSR dp,X | 56 | x | x | x | 2 | 61, 2 | Direct Page Indexed X |
ROL A | 2A | x | x | x | 1 | 2 | Accumulator |
ROL addr | 2E | x | x | x | 3 | 6 | Absolute |
ROL dp | 26 | x | x | x | 2 | 51, 2 | Direct Page |
ROL addr,X | 3E | x | x | x | 3 | 71, 3 | Absolute Indexed X |
ROL dp,X | 36 | x | x | x | 2 | 61, 2 | Direct Page Indexed X |
ROR A | 6A | x | x | x | 1 | 2 | Accumulator |
ROR addr | 6E | x | x | x | 3 | 6 | Absolute |
ROR dp | 66 | x | x | x | 2 | 51, 2 | Direct Page |
ROR addr,X | 7E | x | x | x | 3 | 71, 3 | Absolute Indexed X |
ROR dp,X | 76 | x | x | x | 2 | 61, 2 | Direct Page Indexed X |
Notes:
- 65816: Add 2 cycles if m=0 (16-bit memory/accumulator)
- 65816: Add 1 cycle if low byte of Direct Page register is not 0
- 65C02: Subtract 1 cycle if no page boundary is crossed