This articleneeds additional citations forverification. Please helpimprove this article byadding citations to reliable sources. Unsourced material may be challenged and removed. Find sources: "STM8" – news ·newspapers ·books ·scholar ·JSTOR(January 2018) (Learn how and when to remove this message) |
TheSTM8 is an8-bitmicrocontroller family bySTMicroelectronics. The STM8 microcontrollers use an extended variant of theST7 microcontroller architecture. STM8 microcontrollers are particularly low cost for a full-featured 8-bit microcontroller.[1]
The STM8 is very similar to the earlier ST7, but is better suited as a target forC due to its 16-bit index registers andstack pointer-relative addressing mode. Although internally aHarvard architecture it has "memory bridge" that creates a unified 24-bit address space, allowing code to execute out of RAM (useful forin-system programming of theflash ROM), and data (such aslookup tables) to be accessed out of ROM. On access the "memory bridge" stalls the CPU if required so that RAM-like write access to the flash ROM is possible. Code execution from the EEPROM is denied and creates a reset event. Random access to data above 64K is limited to special "load far" instructions; most operations' memory operands can access at most 128K (a 16-bit base address plus 16-bit offset).
Depending on the device type, the amount of RAM is in the range of 1 to 6 KiB, and the amount of ROM is 4 to 8 KiB (Low density), 16 to 32 KiB (Medium density), or 32 to 96 KiB (High density).
It has the same six registers (A, X, Y, SP, PC, CC) as the ST7, but theindex registers X and Y have been expanded to 16 bits, and theprogram counter has been expanded to 24 bits. Theaccumulator A and the stack pointer remain 8 and 16 bits, respectively.[2]
Thecondition code register has two more defined bits, for a total of seven. There is anoverflow flag, and a second interrupt enable bit, allowing fourinterrupt priority levels.
The STM8 is supported by the open-sourceSmall Device C Compiler, besides C there is the open-source STM8 eForth,[3] an interactive Forth system for the STM8.
The STM8 instruction set is mostly a superset of the ST7's, but it is not completely binary compatible.
Operations on the X and Y registers are extended to 16 bits. Thus, loads and stores access two bytes of memory rather than one. (Also, thehalf-carry flag has been changed to reflect the carry from bit 7 to bit 8 of the 16-bit result, rather than the carry from bit 3 to 4.)
Interrupts push nine bytes of state instead of five as on the ST7.
The multiply instruction stores the 16-bit product in the specified index register (e.g. X), rather than dividing it between X and A.
Indirect addressing modes which fetch an 8-bit address from memory (opcodes92 2x
,92 3x
,92 Bx
,92 6x
,92 Ex
,91 6x
, and91 Ex
) have been deleted; all indirect addressing modes fetch 16-bit addresses. A new prefix byte72
has been added, and used to encode indirect starting with a 16-bit address.
The bit manipulation instructions have been changed to take a 16-bit address and to require the72
prefix byte. The unprefixed opcodes0x
and1x
they formerly occupied are instead used for stack-pointer relative addressing.
Some rarely used branch instructions have had their opcodes changed to require a90
prefix, and the unprefixed opcodes reassigned to signed branches which depend on the V flag.
Load and compare instructions targeting the X register are of little use on the ST7 with addressing modes indexed by the X register. On the STM8, when such operations specify a memory operand indexed by the X register, the register operand is changed to Y. With a90
prefix, the registers are reversed so the index register is Y and the operand register is X.
One major performance difference is that the STM8 fetches 32 bits from ROM per cycle, and many instructions take one cycle to execute. Depending in the instruction length and the number of cycles needed execution from RAM is somewhat slower. The ST7, in contrast, fetches 8 bits per cycle and takes one cycle per instruction byte.
Most STM8 opcode bytes consist of 1 bit of type (one- or two-operand), three bits of addressing mode, and four bits of opcode. Only 6 addressing modes and 12 one-operand opcodes are assigned, leaving encoding space where other instructions are placed.
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Description |
---|---|---|---|---|---|---|---|---|
0 | mode | opcode | One-operand instructions (mode ≠ 1, 2) | |||||
0 | 0 | 0 | 1 | opcode | Additional two-operand instructions | |||
0 | 0 | 1 | 0 | opcode | Conditional branches | |||
0 | opcode | 0 | 0 | 0 | 1 | Other arithmetic instructions (opcode ≠ 1, 2) | ||
0 | opcode | 0 | 0 | 1 | 0 | |||
0 | opcode | 0 | 1 | 0 | 1 | |||
0 | opcode | 1 | 0 | 1 | 1 | |||
1 | mode | opcode | Two-operand instructions (mode ≠ 0, 1) | |||||
1 | 0 | 0 | opcode | Miscellaneous non-arithmetic instructions |
STM8 instructions consist of an optional prefix byte (7216
,9016
,9116
, or9216
), an opcode byte, and a few (up to four, but rarely more than two) bytes of operands. Prefix bytes mostly modify the addressing mode used to specify the memory operand, but in some cases, prefixes72
and90
change the meaning of the opcode byte completely.
Prefix90
exchanges X and Y in the following instruction. In the table below, these variants are combined on one line by writing "X/Y", which means either "X" or "Y". Prefix90
is also used in two places to introduce new opcodes: the BCPL and BCCM instructions, and some branch conditions.
Prefix92
converts instructions with an offset operand (addr16,X) to indirect addressing ([addr8],X). The offset is replaced by the 8-bit address of a 16-bit offset value in memory. It is used only for this function.
Prefix91
has both of the preceding effects, converting (addr16,X) addressing modes to ([addr8],Y).
Prefix72
is used in a number of places, in a much less regular pattern. In some cases, it introduces new addressing modes (particularly an ([addr16],X) 16-bit indirect mode), but it also introduces many completely new operations.
Prefix | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | Operands | Mnemonic | Description |
---|---|---|---|---|---|---|---|---|---|---|---|
— | 0 | 0 | 0 | 0 | opcode | addr8 | OP (addr8,SP) | One-operand instructions (see below) | |||
— | 0 | 0 | 0 | 1 | opcode | addr8 | OP A,(addr8,SP) | Two-operand instructions with stack operand | |||
— | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | addr8 | SUB A,(addr8,SP) | A := A − operand |
— | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | addr8 | CP A,(addr8,SP) | Compare A − operand |
— | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | addr8 | SBC A,(addr8,SP) | A := A − operand − C subtract with borrow |
— | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | addr8 | CPW X,(addr8,SP) | Compare X − operand (16-bit) |
— | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | addr8 | AND A,(addr8,SP) | A := A & operand, bitwise and |
— | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | addr8 | BCP A,(addr8,SP) | Bitwise test A & operand |
— | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | addr8 | LDW Y,(addr8,SP) | Y := operand ( |
— | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | addr8 | LDW (addr8,SP),Y | Operand := Y ( |
— | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | addr8 | XOR A,(addr8,SP) | A := A ^ operand, exclusive-or |
— | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | addr8 | ADC A,(addr8,SP) | A := A + operand + C, add with carry |
— | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | addr8 | OR A,(addr8,SP) | A := A | operand, inclusive or |
— | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | addr8 | ADD A,(addr8,SP) | A := A + operand |
— | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | imm16 | ADDW X,#imm16 | X := X + immediate (= |
— | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | imm16 | SUBW X,#imm16 | X := X − immediate (= |
— | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | addr8 | LDW X,(addr8,SP) | X := operand |
— | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | addr8 | LDW (addr8,SP),X | Operand := X |
72/90 | 0 | 0 | 0 | c | bit | v | operands | Bit operations | |||
72 | 0 | 0 | 0 | 0 | bit | 0 | addr16 soff8 | BTJT addr16,#bit,label | Jump to PC + soff8 if source bit is true (set) | ||
72 | 0 | 0 | 0 | 0 | bit | 1 | addr16 soff8 | BTJF addr16,#bit,label | Jump to PC + soff8 if source bit is false (clear) | ||
72 | 0 | 0 | 0 | 1 | bit | 0 | addr16 | BSETaddr16,#bit | Set specified bit to 1 | ||
72 | 0 | 0 | 0 | 1 | bit | 1 | addr16 | BRESaddr16,#bit | Reset (clear) specified bit to 0 | ||
90 | 0 | 0 | 0 | 1 | bit | 0 | addr16 | BCPLaddr16,#bit | Complement (toggle) selected bit | ||
90 | 0 | 0 | 0 | 1 | bit | 1 | addr16 | BCCMaddr16,#bit | Write carry flag to memory bit | ||
—/90 | 0 | 0 | 1 | 0 | condition | soff8 | Conditional branches (8-bit signed offset) | ||||
— | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | soff8 | JRAlabel | Branch always (true) |
— | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | soff8 | JRFlabel | Branch never (false) |
— | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | soff8 | JRUGTlabel | Branch if unsigned greater than (C=0 and Z=0) |
— | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | soff8 | JRULElabel | Branch if unsigned less than or equal (C=1 or Z=1) |
— | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | soff8 | JRNClabel | Branch if no carry (C=0) |
— | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | soff8 | JRClabel | Branch if carry (C=1) |
— | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | soff8 | JRNElabel | Branch if not equal (Z=0) |
— | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | soff8 | JREQlabel | Branch if equal (Z=1) |
— | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | soff8 | JRNVlabel | Branch if not overflow (V=0) |
90 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | soff8 | JRNHlabel | Branch if not half-carry (H=0) |
— | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | soff8 | JRVlabel | Branch if overflow (V=1) |
90 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | soff8 | JRHlabel | Branch if half-carry (H=1) |
— | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | soff8 | JRPLlabel | Branch if plus (N=0) |
— | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | soff8 | JRMIlabel | Branch if minus (N=1) |
— | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | soff8 | JRSGTlabel | Branch if signed greater than (S=0 and N=V) |
90 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | soff8 | JRNMlabel | Branch if not interrupt mask (I=0) |
— | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | soff8 | JRSLElabel | Branch if signed lower or equal (S=1 or N≠V) |
90 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | soff8 | JRMlabel | Branch if interrupts masked (I=1) |
— | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | soff8 | JRSGElabel | Branch if signed greater or equal (N=V) |
90 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | soff8 | JRILlabel | Branch if interrupt line is low |
— | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | soff8 | JRSLTlabel | Branch if signed less than (N≠V) |
90 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | soff8 | JRIHlabel | Branch if interrupt line is high |
prefix | 0 | mode | opcode | operand | One-operand instructions | ||||||
— | 0 | 0 | 0 | 0 | opcode | addr8 | OP (addr8,SP) | Stack pointer relative | |||
0 | 0 | 0 | 1 | opcode | (reassigned to two-operand instructions with stack; see above) | ||||||
0 | 0 | 1 | 0 | opcode | (reassigned to conditional branches; see above) | ||||||
— | 0 | 0 | 1 | 1 | opcode | addr8 | OPaddr8 | 8-bit absolute address | |||
72 | 0 | 0 | 1 | 1 | opcode | addr16 | OP [addr16] | 16-bit indirect address | |||
92 | 0 | 0 | 1 | 1 | opcode | addr8 | OP [addr8] | 8-bit indirect address of 16-bit address | |||
— | 0 | 1 | 0 | 0 | opcode | — | OP A | Accumulator | |||
72/90 | 0 | 1 | 0 | 0 | opcode | addr16 | OP (addr16,X/Y) | Indexed with 16-bit offset | |||
—/90 | 0 | 1 | 0 | 1 | opcode | — | OPW X/Y | X/Y register (16-bit operation) | |||
72 | 0 | 1 | 0 | 1 | opcode | addr16 | OP addr16 | 16-bit address | |||
—/90 | 0 | 1 | 1 | 0 | opcode | addr8 | OP (addr8,X/Y) | 8-bit address plus X/Y | |||
72 | 0 | 1 | 1 | 0 | opcode | addr16 | OP ([addr16],X) | 16-bit indirect address plus X | |||
92/91 | 0 | 1 | 1 | 0 | opcode | addr8 | OP ([addr8],X/Y) | 8-bit indirect address plus X/Y | |||
—/90 | 0 | 1 | 1 | 1 | opcode | — | OP (X/Y) | Indexed with no offset | |||
prefix | 0 | mode | 0 | 0 | 0 | 0 | operand | NEGoperand | Two's-complement negate | ||
0 | mode | 0 | 0 | 0 | 1 | (reassigned to exchange operations; see following section) | |||||
0 | mode | 0 | 0 | 1 | 0 | (reassigned to other operations; see following section) | |||||
prefix | 0 | mode | 0 | 0 | 1 | 1 | operand | CPLoperand | Ones' complement, logical not | ||
prefix | 0 | mode | 0 | 1 | 0 | 0 | operand | SRLoperand | Shift right logical, msbit cleared, lsbit to carry: (operand:C) := (0:operand) | ||
0 | mode | 0 | 1 | 0 | 1 | (reassigned to other operations; see following section) | |||||
prefix | 0 | mode | 0 | 1 | 1 | 0 | operand | RRCoperand | Rotate right through carry, (operand:C) := (C:operand) | ||
prefix | 0 | mode | 0 | 1 | 1 | 1 | operand | SRAoperand | Shift right arithmetic, msbit preserved, lsbit to carry | ||
prefix | 0 | mode | 1 | 0 | 0 | 0 | operand | SLLoperand | Shift left, msbit to carry: (C:operand) := (operand:0) | ||
prefix | 0 | mode | 1 | 0 | 0 | 1 | operand | RLCoperand | Rotate left through carry, (C:operand) := (operand,C) | ||
prefix | 0 | mode | 1 | 0 | 1 | 0 | operand | DECoperand | Decrement; N and Z set, carry unaffected | ||
0 | mode | 1 | 0 | 1 | 1 | (reassigned to other operations; see following section) | |||||
prefix | 0 | mode | 1 | 1 | 0 | 0 | operand | INCoperand | Increment; N and Z set, carry unaffected | ||
prefix | 0 | mode | 1 | 1 | 0 | 1 | operand | TNZoperand | Test non-zero: set N and Z based on operand value | ||
prefix | 0 | mode | 1 | 1 | 1 | 0 | operand | SWAPoperand | Swap halves of operand (4-bit rotate; 8-bit for SWAPW X and SWAPW Y) | ||
prefix | 0 | mode | 1 | 1 | 1 | 1 | operand | CLRoperand | Set operand to 0, N cleared, Z set | ||
prefix | 0 | mode | opcode | operand | Reassigned opodes [03-7][125B] from one-operand range | ||||||
—/90 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | — | RRWA X/Y | Rotate word right through A: 8-bit right rotate of 24-bit concatenation of X/Y and A; (X:A) := (A:X) |
— | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | addr16 | EXG A,addr16 | Exchange A with memory |
— | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | — | EXG A,XL | Exchange A with X (low half) |
— | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | — | EXGW X,Y | Exchange X with Y (16 bits) |
— | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | — | EXG A,YL | Exchange A with Y (low half) |
— | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | — | (reserved) | |
—/90 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | — | RLWA X/Y | Rotate word left through A: 8-bit left rotate of 24-bit concatenation of X/Y and A; (A:X) := (X:A) |
— | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 0 | addr16 | POPaddr16 | Pop from stack |
—/90 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | — | MUL X/Y,A | X/Y := XL/YL × A |
— | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | imm8 | SUBW SP,#imm | SP := SP − imm8 |
—/90 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | — | DIV X/Y,A | Divide X/Y by A; 16-bit quotient in X/Y, remainder in A |
— | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | — | PREFIX | Instruction prefix72 : modify following opcode |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | — | (reserved) | ||
— | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | imm8 addr16 | MOVaddr16,#imm8 | Move immediate to memory (flags unaffected) |
— | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | addr8 addr8 | MOVaddr8,addr8 | Move memory to memory (flags unaffected) |
— | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 | addr16 addr16 | MOVaddr16,addr16 | Move memory to memory (flags unaffected) |
— | 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | — | DIVW X,Y | Divide X by Y (16 bits); quotient in X, remainder in Y |
0 | 1 | 1 | 1 | 0 | 1 | 0 | 1 | — | (reserved) | ||
0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | — | (reserved) | ||
— | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | addr16 | PUSHaddr16 | Push onto stack |
— | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | imm8 | PUSH #imm8 | Push onto stack |
— | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | imm8 | ADDW SP,#imm8 | SP := SP + imm8 |
— | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | addr8 | LD (addr8,SP),A | Store relative to stack |
— | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | addr8 | LD A,(addr8,SP) | Load relative to stack |
— | 1 | 0 | 0 | opcode | — | Miscellaneous instructions. None implicitly set the condition codes. | |||||
— | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | — | IRET | Return from interrupt (pop CC, A, X, Y, PC) |
— | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | — | RET | Pop 16-bit return address from stack to PC |
— | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | addr24 | INT | Special jump for interrupt vector table |
— | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | — | TRAP | Force trap interrupt |
— | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | — | POP A | Pop A from stack |
—/90 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | — | POPW X/Y | Pop X/Y from stack (16 bits) |
— | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | — | POP CC | Pop condition codes from stack |
— | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | — | RETF | Pop 24-bit return address from stack to PC |
— | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | — | PUSH A | Push A onto stack |
—/90 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | — | PUSHW X/Y | Push X/Y onto stack (16 bits) |
— | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | — | PUSH CC | Push condition codes onto stack |
— | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | — | BREAK | Stop for debugger if present, or NOP |
— | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | — | CCF | Complement (toggle) carry flag |
— | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | addr24 | CALLFaddr24 | Push 24-bit PC; PC := addr24 |
92 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | addr16 | CALLF [addr16] | Indirect far call; address is of 24-bit pointer |
— | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | — | HALT | Halt processor and clocks |
— | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | — | WFI | Wait for interrupt, halting processor but not clocks |
72 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | — | WFE | Wait for event (coprocessor), handling interrupts normally while waiting |
— | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | — | PDY | Instruction prefix90 : swap X and Y in next instruction |
— | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | — | PIY | Instruction prefix91 : PDY plus PIX |
— | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | — | PIX | Instruction prefix92 : use 8-bit memory indirect for operand |
—/90 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | — | LDW X/Y,Y/X | X/Y := Y/X |
—/90 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | — | LDW SP,X/Y | SP := X/Y |
—/90 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | — | LD XH/YH,A | XH/YH := A |
—/90 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | — | LDW X/Y,SP | X/Y := SP |
—/90 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | — | LD XL/YL,A | XL/YL := A |
— | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | — | RCF | Reset (clear) carry flag |
— | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | — | SCF | Set carry flag |
— | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | — | RIM | Reset interrupt mask (enable interrupts) |
— | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | — | SIM | Set interrupt mask (disable interrupts) |
— | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | — | RVF | Reset (clear) overflow flag |
— | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | — | NOP | No operation |
—/90 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | — | LD A,XH/YH | A := XH/YH |
—/90 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | — | LD A,XL/YL | A := XL/YL |
Prefix | 1 | mode | opcode | operand | Two-operand instructions A := A op operand | ||||||
— | 0 | 0 | 0 | 0 | opcode | addr8 | OP A,(addr8,SP) | (opcodes 6, 7, C, D differ; see above) | |||
— | 1 | 0 | 0 | opcode | (reassigned to miscellaneous instructions; see above) | ||||||
— | 1 | 0 | 1 | 0 | opcode | imm8 | OP A,#imm8 | 8-bit immediate operand(forbidden as destination) | |||
— | 1 | 0 | 1 | 1 | opcode | addr8 | OP A,addr8 | 8-bit absolute address(forbidden for jump/call) | |||
— | 1 | 1 | 0 | 0 | opcode | addr16 | OP A,addr16 | 16-bit absolute address | |||
72 | 1 | 1 | 0 | 0 | opcode | addr16 | OP A,[addr16] | 16-bit indirect address | |||
92 | 1 | 1 | 0 | 0 | opcode | addr8 | OP A,[addr8] | 8-bit indirect address of 16-bit address | |||
—/90 | 1 | 1 | 0 | 1 | opcode | addr16 | OP A,(addr16,X/Y) | Indexed with 16-bit offset | |||
72 | 1 | 1 | 0 | 1 | opcode | addr16 | OP A,([addr16],X) | 16-bit indirect + X | |||
92/91 | 1 | 1 | 0 | 1 | opcode | addr16 | OP A,([addr8],X/Y) | 8-bit indirect + X/Y | |||
—/90 | 1 | 1 | 1 | 0 | opcode | addr8 | OP A,(addr8,X/Y) | Indexed with 8-bit offset | |||
—/90 | 1 | 1 | 1 | 1 | opcode | — | OP A,(X/Y) | Indexed with no offset | |||
prefix | 1 | mode | 0 | 0 | 0 | 0 | operand | SUB A,operand | A := A − operand | ||
prefix | 1 | mode | 0 | 0 | 0 | 1 | operand | CP A,operand | Compare A − operand | ||
prefix | 1 | mode | 0 | 0 | 1 | 0 | operand | SBC A,operand | A := A − operand − C subtract with borrow | ||
prefix | 1 | mode | 0 | 0 | 1 | 1 | operand | CPW X/Y,operand | Compare X/Y − operand (16 bit); compare Y/X if operand mode is indexed by X/Y (opcodes D3, E3, F3) | ||
prefix | 1 | mode | 0 | 1 | 0 | 0 | operand | AND A,operand | A := A & operand, bitwise and | ||
prefix | 1 | mode | 0 | 1 | 0 | 1 | operand | BCP A,operand | Bitwise test A & operand | ||
prefix | 1 | mode | 0 | 1 | 1 | 0 | operand | LD A,operand | A := operand | ||
prefix | 1 | mode | 0 | 1 | 1 | 1 | operand | LDoperand,A | Operand := A (mode 2 | ||
prefix | 1 | mode | 1 | 0 | 0 | 0 | operand | XOR A,operand | A := A ^ operand, exclusive-or | ||
prefix | 1 | mode | 1 | 0 | 0 | 1 | operand | ADC A,operand | A := A + operand + C, add with carry | ||
prefix | 1 | mode | 1 | 0 | 1 | 0 | operand | OR A,operand | A := A | operand, inclusive or | ||
prefix | 1 | mode | 1 | 0 | 1 | 1 | operand | ADD A,operand | A := A + operand | ||
prefix | 1 | mode | 1 | 1 | 0 | 0 | operand | JPoperand | Low 16 bits of PC := operand, unconditional jump (modes 2 | ||
prefix | 1 | mode | 1 | 1 | 0 | 1 | operand | CALLoperand | Push 16-bit PC, low 16 bits of PC := operand (modes 2 | ||
prefix | 1 | mode | 1 | 1 | 1 | 0 | operand | LDW X/Y,operand | Load X/Y := operand; use 16 instead of 90 1E for LDW Y,(addr8,SP) | ||
prefix | 1 | mode | 1 | 1 | 1 | 1 | operand | LDWoperand,X/Y | Operand := X/Y (16-bit, mode 2 | ||
Prefix | 1 | mode | opcode | operand | Reassigned opcodes A7, AC, BC, AD, BD, AF from two-operand range | ||||||
—/90 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | addr24 | LDF (addr24,X/Y),A | Load far (= |
92/91 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | addr16 | LDF ([addr16],X/Y),A | 16-bit address of 24-bit pointer |
— | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | addr24 | JPFaddr24 | PC := addr24 (= |
92 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | addr16 | JPF [addr16] | Indirect far jump; address is of 24-bit pointer |
— | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | addr24 | LDF A,addr24 | Load far (= |
92 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | addr16 | LDF A,[addr16] | Load far, 16-bit address of 24-bit pointer |
— | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | soff8 | CALLRlabel | Push 16-bit PC, PC := PC + operand (= |
— | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | addr24 | LDFaddr24,A | Operand := A (= |
92 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | addr16 | LDF [addr16],A | Operand := A, 16-bit address of 24-bit pointer |
—/90 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | addr24 | LDF A,(addr24,X/Y) | Load far (= |
92/91 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | addr16 | LDF A,([addr16],X/Y) | 16-bit address of 24-bit pointer |
72 | 1 | mode | opcode | operand | Index register arithmetic (16-bit) X/Y := X/Y ± operand | ||||||
72 | 1 | 0 | 1 | 0 | opcode | imm16 | OPW X/Y,#imm16 | 16-bit immediate | |||
72 | 1 | 0 | 1 | 1 | opcode | addr16 | OPW X/Y,addr16 | 16-bit absolute | |||
72 | 1 | 1 | 1 | 1 | opcode | addr8 | OPW X/Y,(addr8,SP) | Stack-relative | |||
72 | 1 | mode | 0 | 0 | 0 | 0 | operand | SUBW X,operand | X := X − operand (prefer opcode 1D for SUBW X,#imm16) | ||
72 | 1 | mode | 0 | 0 | 1 | 0 | operand | SUBW Y,operand | Y := Y − operand | ||
72 | 1 | mode | 1 | 0 | 0 | 1 | operand | ADDW Y,operand | Y := Y + operand | ||
72 | 1 | mode | 1 | 0 | 1 | 1 | operand | ADDW X,operand | X := X + operand (prefer opcode 1C for ADDW X,#imm16) |
For CPW and LDW instructions where the operand addressing mode is indexed by X, the STM8 uses the Y register by default instead of X. Applying a90
prefix exchanges X and Y so the register is X and the addressing mode is indexed by Y.