Instruction Reference
The 6502 has a relatively basic set of instructions, many having similar functions (e.g. memory access, arithmetic, etc.). The following sections list the complete set of 56 instructions in functional groups.
ADC | AND | ASL | BCC | BCS | BEQ | BIT | BMI | BNE | BPL | BRK | BVC | BVS | CLC |
CLD | CLI | CLV | CMP | CPX | CPY | DEC | DEX | DEY | EOR | INC | INX | INY | JMP |
JSR | LDA | LDX | LDY | LSR | NOP | ORA | PHA | PHP | PLA | PLP | ROL | ROR | RTI |
RTS | SBC | SEC | SED | SEI | STA | STX | STY | TAX | TAY | TSX | TXA | TXS | TYA |
Addressing Modes
The 6502 processor provides several ways in which memory locations can be addressed. Some instructions support several different modes while others may only support one. In addition the two index registers can not always be used interchangeably. This lack of orthogonality in the instruction set is one of the features that makes the 6502 trickier to program well.Implicit" | Accumulator" | Immediate" |
Zero page" | Zero page X" | Zero page Y" |
Relative" | Absolute" | Absolute X" |
Absolute Y" | Indirect" | Indexed indirect" |
Indirect indexed" |
Load/Store Operations | ||||||||||||||||||||||||||||||||||||||||
These instructions transfer a single byte between memory and one of the registers. Load operations set the negative (N) and zero (Z) flags depending on the value of transferred. Store operations do not affect the flag settings. |
||||||||||||||||||||||||||||||||||||||||
LDA |
Load Accumulator
A,Z,N = M A ⇐ M |
Loads a byte of memory into the accumulator setting the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
LDX |
Load X Register
X,Z,N = M X ⇐ M |
Loads a byte of memory into the X register setting the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
LDY |
Load Y Register
Y,Z,N = M Y ⇐ M |
Loads a byte of memory into the Y register setting the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
STA |
Store Accumulator
M ⇐ A |
Stores the contents of the accumulator into memory. |
|
| ||||||||||||||||||||||||||||||||||||
STX |
Store X Register
M ⇐ X |
Stores the contents of the X register into memory. |
|
| ||||||||||||||||||||||||||||||||||||
STY |
Store Y Register
M ⇐ Y |
Stores the contents of the Y register into memory. |
|
| ||||||||||||||||||||||||||||||||||||
Register Transfers | ||||||||||||||||||||||||||||||||||||||||
The contents of the X and Y registers can be moved to or from the accumulator, setting the negative (N) and zero (Z) flags as appropriate. |
||||||||||||||||||||||||||||||||||||||||
TAX |
Transfer accumulator to X
X ⇐ A |
Copies the current contents of the accumulator into the X register and sets the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
TAY |
Transfer accumulator to Y
Y ⇐ A |
Copies the current contents of the accumulator into the Y register and sets the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
TXA |
Transfer X to accumulator
A ⇐ X |
Copies the current contents of the X register into the accumulator and sets the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
TYA |
Transfer Y to accumulator
A ⇐ Y |
Copies the current contents of the Y register into the accumulator and sets the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
Stack Operations | ||||||||||||||||||||||||||||||||||||||||
The 6502 microprocessor supports a 256 byte stack fixed between memory locations 0x0100 and 0x01FF. A special 8-bit register, S, is used to keep track of the next free byte of stack space. Pushing a byte on to the stack causes the value to be stored at the current free location (e.g. 0x0100,S) and then the stack pointer is post decremented. Pull operations reverse this procedure. The stack register can only be accessed by transferring its value to or from the X register. Its value is automatically modified by push/pull instructions, subroutine calls and returns, interrupts and returns from interrupts. |
||||||||||||||||||||||||||||||||||||||||
TSX |
Transfer stack pointer to X
X ⇐ S |
Copies the current contents of the stack register into the X register and sets the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
TXS |
Transfer X to stack pointer
S ⇐ X |
Copies the current contents of the X register into the stack register. |
|
| ||||||||||||||||||||||||||||||||||||
PHA | Push accumulator on stack |
Pushes a copy of the accumulator on to the stack. |
|
|
||||||||||||||||||||||||||||||||||||
PHP | Push processor status on stack |
Pushes a copy of the status flags on to the stack. |
|
| ||||||||||||||||||||||||||||||||||||
PLA | Pull accumulator from stack |
Pulls an 8 bit value from the stack and into the accumulator. The zero and negative flags are set as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
PLP | Pull processor status from stack |
Pulls an 8 bit value from the stack and into the processor flags. The flags will take on new states as determined by the value pulled. |
|
| ||||||||||||||||||||||||||||||||||||
Logical | ||||||||||||||||||||||||||||||||||||||||
The following instructions perform logical operations on the contents of the accumulator and another value held in memory. The BIT instruction performs a logical AND to test the presence of bits in the memory value to set the flags but does not keep the result. |
||||||||||||||||||||||||||||||||||||||||
AND |
Logical AND
A,Z,N = A&M |
A logical AND is performed, bit by bit, on the accumulator contents using the contents of a byte of memory. |
|
| ||||||||||||||||||||||||||||||||||||
EOR |
Exclusive OR
A,Z,N = A^M |
An exclusive OR is performed, bit by bit, on the accumulator contents using the contents of a byte of memory. |
|
| ||||||||||||||||||||||||||||||||||||
ORA |
Logical Inclusive OR
A,Z,N = A|M |
An inclusive OR is performed, bit by bit, on the accumulator contents using the contents of a byte of memory. |
|
| ||||||||||||||||||||||||||||||||||||
BIT |
Bit Test
A & M, N = M7, V = M6 |
This instructions is used to test if one or more bits are set in a target memory location. The mask pattern in A is ANDed with the value in memory to set or clear the zero flag, but the result is not kept. Bits 7 and 6 of the value from memory are copied into the N and V flags. |
|
| ||||||||||||||||||||||||||||||||||||
Arithmetic | ||||||||||||||||||||||||||||||||||||||||
The arithmetic operations perform addition and subtraction on the contents of the accumulator. The compare operations allow the comparison of the accumulator and X or Y with memory values. |
||||||||||||||||||||||||||||||||||||||||
ADC |
Add with Carry
A,Z,C,N = A+M+C |
This instruction adds the contents of a memory location to the accumulator together with the carry bit. If overflow occurs the carry bit is set, this enables multiple byte addition to be performed. |
|
| ||||||||||||||||||||||||||||||||||||
SBC |
Subtract with Carry
A,Z,C,N = A-M-(1-C) |
This instruction subtracts the contents of a memory location to the accumulator together with the not of the carry bit. If overflow occurs the carry bit is clear, this enables multiple byte subtraction to be performed. |
|
| ||||||||||||||||||||||||||||||||||||
CMP |
Compare accumulator
Z,C,N = A-M |
This instruction compares the contents of the accumulator with another memory held value and sets the zero and carry flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
CPX |
Compare X register
Z,C,N = X-M |
This instruction compares the contents of the X register with another memory held value and sets the zero and carry flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
CPY |
Compare Y register
Z,C,N = Y-M |
This instruction compares the contents of the Y register with another memory held value and sets the zero and carry flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
Increments & Decrements | ||||||||||||||||||||||||||||||||||||||||
Increment or decrement a memory location or one of the X or Y registers by one setting the negative (N) and zero (Z) flags as appropriate, |
||||||||||||||||||||||||||||||||||||||||
INC |
Increment a memory location
M,Z,N = M+1 |
Adds one to the value held at a specified memory location setting the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
INX |
Increment the X register
X,Z,N = X+1 |
Adds one to the X register setting the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
INY |
Increment the Y register
Y,Z,N = Y+1 |
Adds one to the Y register setting the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
DEC |
Decrement a memory location
M,Z,N = M-1 |
Subtracts one from the value held at a specified memory location setting the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
DEX |
Decrement the X register
X,Z,N = X-1 |
Subtracts one from the X register setting the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
DEY |
Decrement the Y register
Y,Z,N = Y-1 |
Subtracts one from the Y register setting the zero and negative flags as appropriate. |
|
| ||||||||||||||||||||||||||||||||||||
Shifts | ||||||||||||||||||||||||||||||||||||||||
Shift instructions cause the bits within either a memory location or the accumulator to be shifted by one bit position. The rotate instructions use the contents if the carry flag (C) to fill the vacant position generated by the shift and to catch the overflowing bit. The arithmetic and logical shifts shift in an appropriate 0 or 1 bit as appropriate but catch the overflow bit in the carry flag (C). |
||||||||||||||||||||||||||||||||||||||||
ASL |
Arithmetic Shift Left
A,Z,C,N = M*2 or M,Z,C,N = M*2 |
This operation shifts all the bits of the accumulator or memory contents one bit left. Bit 0 is set to 0 and bit 7 is placed in the carry flag. The effect of this operation is to multiply the memory contents by 2 (ignoring 2's complement considerations), setting the carry if the result will not fit in 8 bits. |
|
| ||||||||||||||||||||||||||||||||||||
LSR |
Logical Shift Right
A,C,Z,N = A/2 or M,C,Z,N = M/2 |
Each of the bits in A or M is shift one place to the right. The bit that was in bit 0 is shifted into the carry flag. Bit 7 is set to zero. |
|
| ||||||||||||||||||||||||||||||||||||
ROL | Rotate Left |
Move each of the bits in either A or M one place to the left. Bit 0 is filled with the current value of the carry flag whilst the old bit 7 becomes the new carry flag value. |
|
| ||||||||||||||||||||||||||||||||||||
ROR | Rotate Right |
Move each of the bits in either A or M one place to the right. Bit 7 is filled with the current value of the carry flag whilst the old bit 0 becomes the new carry flag value. |
|
| ||||||||||||||||||||||||||||||||||||
Jumps & Calls | ||||||||||||||||||||||||||||||||||||||||
The following instructions modify the program counter causing a break to normal sequential execution. The JSR instruction pushes the old PC onto the stack before changing it to the new location allowing a subsequent RTS to return execution to the instruction after the call. |
||||||||||||||||||||||||||||||||||||||||
JMP | Jump to another location |
Sets the program counter to the address specified by the operand. |
|
| ||||||||||||||||||||||||||||||||||||
JSR | Jump to a subroutine |
The JSR instruction pushes the address (minus one) of the return point on to the stack and then sets the program counter to the target memory address. |
|
| ||||||||||||||||||||||||||||||||||||
RTS | Return from subroutine |
The RTS instruction is used at the end of a subroutine to return to the calling routine. It pulls the program counter (minus one) from the stack. |
|
| ||||||||||||||||||||||||||||||||||||
Branches | ||||||||||||||||||||||||||||||||||||||||
Branch instructions break the normal sequential flow of execution by changing the program counter if a specified condition is met. All the conditions are based on examining a single bit within the processor status. |
||||||||||||||||||||||||||||||||||||||||
BCC | Branch if carry flag clear |
If the carry flag is clear then add the relative displacement to the program counter to cause a branch to a new location. |
|
| ||||||||||||||||||||||||||||||||||||
BCS | Branch if carry flag set |
If the carry flag is set then add the relative displacement to the program counter to cause a branch to a new location. |
|
| ||||||||||||||||||||||||||||||||||||
BEQ | Branch if zero flag set |
If the zero flag is set then add the relative displacement to the program counter to cause a branch to a new location. |
|
| ||||||||||||||||||||||||||||||||||||
BMI | Branch if negative flag set |
If the negative flag is set then add the relative displacement to the program counter to cause a branch to a new location. |
|
| ||||||||||||||||||||||||||||||||||||
BNE | Branch if zero flag clear |
If the zero flag is clear then add the relative displacement to the program counter to cause a branch to a new location. |
|
| ||||||||||||||||||||||||||||||||||||
BPL | Branch if negative flag clear |
If the negative flag is clear then add the relative displacement to the program counter to cause a branch to a new location. |
|
| ||||||||||||||||||||||||||||||||||||
BVC | Branch if overflow flag clear |
If the overflow flag is clear then add the relative displacement to the program counter to cause a branch to a new location. |
|
| ||||||||||||||||||||||||||||||||||||
BVS | Branch if overflow flag set |
If the overflow flag is set then add the relative displacement to the program counter to cause a branch to a new location. |
|
| ||||||||||||||||||||||||||||||||||||
Status Flag Changes | ||||||||||||||||||||||||||||||||||||||||
The following instructions change the values of specific status flags. |
||||||||||||||||||||||||||||||||||||||||
CLC |
Clear carry flag
C = 0 |
C |
|
| ||||||||||||||||||||||||||||||||||||
CLD |
Clear decimal mode flag
D = 0 |
D |
|
| ||||||||||||||||||||||||||||||||||||
CLI |
Clear interrupt disable flag
I = 0 |
Clears the interrupt disable flag allowing normal interrupt requests to be serviced. |
|
| ||||||||||||||||||||||||||||||||||||
CLV |
Clear overflow flag
V = 0 |
Clears the overflow flag. |
|
| ||||||||||||||||||||||||||||||||||||
SEC |
Set carry flag
C = 1 |
Set the carry flag to one. |
|
| ||||||||||||||||||||||||||||||||||||
SED |
Set decimal mode flag
D = 1 |
Set the decimal mode flag to one. |
|
| ||||||||||||||||||||||||||||||||||||
SEI |
Set interrupt disable flag
I = 1 |
Set the interrupt disable flag to one. |
|
| ||||||||||||||||||||||||||||||||||||
System Functions | ||||||||||||||||||||||||||||||||||||||||
The remaining instructions perform useful but rarely used functions. |
||||||||||||||||||||||||||||||||||||||||
BRK | Force an interrupt |
The BRK instruction forces the generation of an interrupt request. The program counter and processor status are pushed on the stack then the IRQ interrupt vector at 0xFFFE/F is loaded into the PC and the break flag in the status set to one. |
|
| ||||||||||||||||||||||||||||||||||||
NOP | No Operation |
The NOP instruction causes no changes to the processor other than the normal incrementing of the program counter to the next instruction. |
|
| ||||||||||||||||||||||||||||||||||||
RTI | Return from Interrupt |
The RTI instruction is used at the end of an interrupt processing routine. It pulls the processor flags from the stack followed by the program counter. |
|
|
Addressing Modes
The 6502 processor provides several ways in which memory locations can be addressed. Some instructions support several different modes while others may only support one. In addition the two index registers can not always be used interchangeably. This lack of orthogonality in the instruction set is one of the features that makes the 6502 trickier to program well.
Implicit
For many 6502 instructions the source and destination of the information to be manipulated is implied directly by the function of the instruction itself and no further operand needs to be specified. Operations like 'Clear Carry Flag' (#CLC) and 'Return from Subroutine' (#RTS) are implicit.
Accumulator
Some instructions have an option to operate directly upon the accumulator. The programmer specifies this by using a special operand value, 'A'. For example:
LSR A ;Logical shift right one bit
ROR A ;Rotate right one bit
Immediate
Immediate addressing allows the programmer to directly specify an 8 bit constant within the instruction. It is indicated by a '#' symbol followed by an numeric expression. For example:
LDA #10 ;Load 10 ($0A) into the accumulator
LDX #LO LABEL ;Load the LSB of a 16 bit address into X
LDY #HI LABEL ;Load the MSB of a 16 bit address into Y
Zero Page
An instruction using zero page addressing mode has only an 8 bit address operand. This limits it to addressing only the first 256 bytes of memory (e.g. $0000 to $00FF) where the most significant byte of the address is always zero. In zero page mode only the least significant byte of the address is held in the instruction making it shorter by one byte (important for space saving) and one less memory fetch during execution (important for speed).
An assembler will automatically select zero page addressing mode if the operand evaluates to a zero page address and the instruction supports the mode (not all do).
LDA $00 ;Load accumulator from $00
ASL ANSWER ;Shift labelled location ANSWER left
Zero Page,X
The address to be accessed by an instruction using indexed zero page addressing is calculated by taking the 8 bit zero page address from the instruction and adding the current value of the X register to it. For example if the X register contains $0F and the instruction LDA $80,X is executed then the accumulator will be loaded from $008F (e.g. $80 + $0F => $8F).
NB: The address calculation wraps around if the sum of the base address and the register exceed $FF. If we repeat the last example but with $FF in the X register then the accumulator will be loaded from $007F (e.g. $80 + $FF => $7F) and not $017F.
STY $10,X ;Save the Y register at location on zero page
AND TEMP,X ;Logical AND accumulator with a zero page value
Zero Page,Y
The address to be accessed by an instruction using indexed zero page addressing is calculated by taking the 8 bit zero page address from the instruction and adding the current value of the Y register to it. This mode can only be used with the #LDX and #STX instructions.
LDX $10,Y ;Load the X register from a location on zero page
STX TEMP,Y ;Store the X register in a location on zero page
Relative
Relative addressing mode is used by branch instructions (e.g. #BEQ, #BNE, etc.) which contain a signed 8 bit relative offset (e.g. -128 to +127) which is added to program counter if the condition is true. As the program counter itself is incremented during instruction execution by two the effective address range for the target instruction must be with -126 to +129 bytes of the branch.
BEQ LABEL ;Branch if zero flag set to LABEL
BNE *+4 ;Skip over the following 2 byte instruction
Absolute
Instructions using absolute addressing contain a full 16 bit address to identify the target location.
JMP $1234 ;Jump to location $1234
JSR WIBBLE ;Call subroutine WIBBLE
Absolute,X
The address to be accessed by an instruction using X register indexed absolute addressing is computed by taking the 16 bit address from the instruction and added the contents of the X register. For example if X contains $92 then an STA $2000,X instruction will store the accumulator at $2092 (e.g. $2000 + $92).
STA $3000,X ;Store accumulator between $3000 and $30FF
ROR CRC,X ;Rotate right one bit
Absolute,Y
The Y register indexed absolute addressing mode is the same as the previous mode only with the contents of the Y register added to the 16 bit address from the instruction.
AND $4000,Y ;Perform a logical AND with a byte of memory
STA MEM,Y ;Store accumulator in memory
Indirect
#JMP is the only 6502 instruction to support indirection. The instruction contains a 16 bit address which identifies the location of the least significant byte of another 16 bit memory address which is the real target of the instruction.
For example if location $0120 contains $FC and location $0121 contains $BA then the instruction JMP ($0120) will cause the next instruction execution to occur at $BAFC (e.g. the contents of $0120 and $0121).
JMP ($FFFC) ;Force a power on reset
JMP (TARGET) ;Jump via a labelled memory area
Indexed Indirect
Indexed indirect addressing is normally used in conjunction with a table of address held on zero page. The address of the table is taken from the instruction and the X register added to it (with zero page wrap around) to give the location of the least significant byte of the target address.
LDA ($40,X) ;Load a byte indirectly from memory
STA (MEM,X) ;Store accumulator indirectly into memory
Indirect Indexed
Indirect indirect addressing is the most common indirection mode used on the 6502. In instruction contains the zero page location of the least significant byte of 16 bit address. The Y register is dynamically added to this value to generated the actual target address for operation.
LDA ($40),Y ;Load a byte indirectly from memory
STA (DST),Y ;Store accumulator indirectly into memory