JMP (short for "JuMP") is the mnemonic for a machine language instruction which unconditionally transfers program execution to the specified address. To those familiar with BASIC programming; this is the machine language equivalent to GOTO.
Vectors and indirectly addressed JuMPs
JMP is the only instruction in the 65xx instruction set which supports the purely indirect addressing mode, and this indirect JMP provides for the use of vectors: While the user has no easy access to modify the contents of either BASIC or KERNAL ROM, both these parts of the system makes ample use of vectors, set in RAM that the user can modify. This allows the user to "divert" parts of BASIC or KERNAL to custom routines.
JMP-ing into a subroutine
Normally, subroutines are called with a JSR, but consider some routine that prints out a message, e.g. fetched from a table of several messages. After printing all characters of the messages, a carriage return control character is to be printed, before the message routine ends in an RTS. The "standard way" to print the this would be:
but since the call to a subroutine (the JSR CHROUT) is immediately followed by an RTS, there is the option of saving a byte and 9 machine cycles by JuMP-ing directly into the subroutine:
LDA #13 Print carriage return JMP CHROUT Leave this routine through CHROUT
This will first print out the required character, but when the CPU encounters the "final RTS" at the end of the CHROUT routine, this serves to return from not just CHROUT, but of the entire message-printing routine.
Emulating JMP (addr,X)
The JMP (addr,X) instruction is present in later 65xx processors (65C02, 65C802/65C816). It behaves like JMP (addr), except it fetches the 16-bit value from addr+X. This is a common way to realize a table-driven jump.
The least-problematic way to implement this is using RTI:
; Jump to address stored at addr+X LDA addr+1,x ; high byte first PHA LDA addr,x PHA PHP ; RTI expects processor flags on top RTI
The RTS version is faster, but slightly more tricky, because it adds one to the address it pulls from the stack. This requires that every entry in the jump table have one subtracted from it. This could be done by the code, but it's tedious because the low byte must be decremented first, while the high byte needs to be pushed first. Thus, it's preferable to simply subtract one from each entry in the assembly source text:
; Jump to address stored at addr+X LDA table+1,x PHA LDA table,x PHA RTS table: .word action0-1, action1-1, action2-1 ; ...
The benefit of the RTS version is that it's three clock cycles faster than the RTI version, due to not having to push the flags. The disadvantage is that you must adjust every table entry by -1.
JMP supports 2 different addressing modes, as shown in the table at right. In the assembler formats listed, nnnn is a two-byte (16-bit) address.