STM8

{{more citations needed|date=January 2018}}

File:Philips BT6000A-12 - board - STMicroelectronics STM8S003K3-8970.jpg

File:Stmicro stm8l152 goodspeed mz 10x.jpg

The STM8 is an 8-bit microcontroller family by STMicroelectronics. The STM8 microcontrollers use an extended variant of the ST7 microcontroller architecture. STM8 microcontrollers are particularly low cost for a full-featured 8-bit microcontroller.{{cite web |title=ST STM8 |first=Jay |last=Carlson |date=September 15, 2017 |url= https://jaycarlson.net/pf/st-stm8/ |access-date=2018-06-12}}

Architecture

The STM8 is very similar to the earlier ST7, but is better suited as a target for C due to its 16-bit index registers and stack pointer-relative addressing mode. Although internally a Harvard architecture it has "memory bridge" that creates a unified 24-bit address space, allowing code to execute out of RAM (useful for in-system programming of the flash ROM), and data (such as lookup 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 the index registers X and Y have been expanded to 16 bits, and the program counter has been expanded to 24 bits. The accumulator A and the stack pointer remain 8 and 16 bits, respectively.{{cite web |title=PM0044: STM8 CPU programming manual |date=September 2011 |id=Document 13590 Rev 3 |publisher=STMicroelectronics |url=http://www.st.com/content/ccc/resource/technical/document/programming_manual/43/24/13/9a/89/df/45/ed/CD00161709.pdf/files/CD00161709.pdf/jcr:content/translations/en.CD00161709.pdf |access-date=2018-06-10}}

The condition code register has two more defined bits, for a total of seven. There is an overflow flag, and a second interrupt enable bit, allowing four interrupt priority levels.

Subfamilies

  • STM8AF automobile
  • STM8AL automobile low-power
  • STM8L low-power
  • STM8S general purpose
  • STM8T touch-sensing
  • STLUX lighting control
  • STNRG Pulse-width modulation-controllers

Compiler support

The STM8 is supported by the open-source Small Device C Compiler, besides C there is the open-source STM8 eForth,{{cite web |title=STM8 eForth - a user friendly Forth for simple µCs with docs |website=GitHub |date=18 November 2022 |url=https://github.com/TG9541/stm8ef}} an interactive Forth system for the STM8.

Changes compared to ST7

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, the half-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 (opcodes 92 2x, 92 3x, 92 Bx, 92 6x, 92 Ex, 91 6x, and 91 Ex) have been deleted; all indirect addressing modes fetch 16-bit addresses. A new prefix byte 72 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 the 72 prefix byte. The unprefixed opcodes 0x and 1x they formerly occupied are instead used for stack-pointer relative addressing.

Some rarely used branch instructions have had their opcodes changed to require a 90 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 a 90 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.

Instruction set

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.

class="wikitable" style="text-align:center"

|+ STM8 instruction overview{{r|pm0044}}

! 7

6543210Description
0colspan=3| modecolspan=4| opcodealign=left| One-operand instructions (mode ≠ 1, 2)
0001colspan=4| opcodealign=left| Additional two-operand instructions
0010colspan=4| opcodealign=left| Conditional branches
0colspan=3| opcode0001rowspan=4 align=left| Other arithmetic instructions
(opcode ≠ 1, 2)
0colspan=3| opcode0010
0colspan=3| opcode0101
0colspan=3| opcode1011
1colspan=3| modecolspan=4| opcodealign=left| Two-operand instructions (mode ≠ 0, 1)
100colspan=5| opcodealign=left| Miscellaneous non-arithmetic instructions

STM8 instructions consist of an optional prefix byte (7216, 9016, 9116, or 9216), 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, prefixes 72 and 90 change the meaning of the opcode byte completely.

Prefix 90 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". Prefix 90 is also used in two places to introduce new opcodes: the BCPL and BCCM instructions, and some branch conditions.

Prefix 92 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.

Prefix 91 has both of the preceding effects, converting (addr16,X) addressing modes to ([addr8],Y).

Prefix 72 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.

class="wikitable" style="text-align:center"

|+ STM8 instruction set{{r|pm0044}}

! Prefix

76543210OperandsMnemonicDescription
— || 0 || 0 || 0 || 0 ||colspan=4| opcode || addr8 ||align=left| OP (addr8,SP) || One-operand instructions (see below)
— || 0 || 0 || 0 || 1 ||colspan=4| opcode || addr8 ||align=left| OP A,(addr8,SP) || Two-operand instructions with stack operand
00010000addr8align=left| SUB A,(addr8,SP)align=left| A := A − operand
00010001addr8align=left| CP A,(addr8,SP)align=left| Compare A − operand
00010010addr8align=left| SBC A,(addr8,SP)align=left| A := A − operand − C subtract with borrow
00010011addr8align=left| CPW X,(addr8,SP)align=left| Compare X − operand (16-bit)
00010100addr8align=left| AND A,(addr8,SP)align=left| A := A & operand, bitwise and
00010101addr8align=left| BCP A,(addr8,SP)align=left| Bitwise test A & operand
00010110addr8align=left| LDW Y,(addr8,SP)align=left| Y := operand ({{s|LD A,(addr8,SP)}} assigned to opcode 7B)
00010111addr8align=left| LDW (addr8,SP),Yalign=left| Operand := Y ({{s|LD (addr8,SP),A}} assigned to opcode 6B)
00011000addr8align=left| XOR A,(addr8,SP)align=left| A := A ^ operand, exclusive-or
00011001addr8align=left| ADC A,(addr8,SP)align=left| A := A + operand + C, add with carry
00011010addr8align=left| OR A,(addr8,SP)align=left| A := A {{!}} operand, inclusive or
00011011addr8align=left| ADD A,(addr8,SP)align=left| A := A + operand
00011100imm16align=left| ADDW X,#imm16align=left| X := X + immediate (={{s|JP (addr8,SP)}})
00011101imm16align=left| SUBW X,#imm16align=left| X := X − immediate (={{s|CALL (addr8,SP)}})
00011110addr8align=left| LDW X,(addr8,SP)align=left| X := operand
00011111addr8align=left| LDW (addr8,SP),Xalign=left| Operand := X
colspan=12|
72/90 || 0 || 0 || 0 || c ||colspan=3| bit || v || operands ||colspan=2| Bit operations
720000colspan=3| bit0addr16 soff8align=left| BTJT addr16,#bit,labelalign=left| Jump to PC + soff8 if source bit is true (set)
720000colspan=3| bit1addr16 soff8align=left| BTJF addr16,#bit,labelalign=left| Jump to PC + soff8 if source bit is false (clear)
720001colspan=3| bit0addr16align=left| BSET addr16,#bitalign=left| Set specified bit to 1
720001colspan=3| bit1addr16align=left| BRES addr16,#bitalign=left| Reset (clear) specified bit to 0
900001colspan=3| bit0addr16align=left| BCPL addr16,#bitalign=left| Complement (toggle) selected bit
900001colspan=3| bit1addr16align=left| BCCM addr16,#bitalign=left| Write carry flag to memory bit
colspan=12|
—/90 || 0 || 0 || 1 || 0 ||colspan=4| condition || soff8 ||colspan=2| Conditional branches (8-bit signed offset)
00100000soff8align=left| JRA labelalign=left| Branch always (true)
00100001soff8align=left| JRF labelalign=left| Branch never (false)
00100010soff8align=left| JRUGT labelalign=left| Branch if unsigned greater than (C=0 and Z=0)
00100011soff8align=left| JRULE labelalign=left| Branch if unsigned less than or equal (C=1 or Z=1)
00100100soff8align=left| JRNC labelalign=left| Branch if no carry (C=0)
00100101soff8align=left| JRC labelalign=left| Branch if carry (C=1)
00100110soff8align=left| JRNE labelalign=left| Branch if not equal (Z=0)
00100111soff8align=left| JREQ labelalign=left| Branch if equal (Z=1)
00101000soff8align=left| JRNV labelalign=left| Branch if not overflow (V=0)
9000101000soff8align=left| JRNH labelalign=left| Branch if not half-carry (H=0)
00101001soff8align=left| JRV labelalign=left| Branch if overflow (V=1)
9000101001soff8align=left| JRH labelalign=left| Branch if half-carry (H=1)
00101010soff8align=left| JRPL labelalign=left| Branch if plus (N=0)
00101011soff8align=left| JRMI labelalign=left| Branch if minus (N=1)
00101100soff8align=left| JRSGT labelalign=left| Branch if signed greater than (S=0 and N=V)
9000101100soff8align=left| JRNM labelalign=left| Branch if not interrupt mask (I=0)
00101101soff8align=left| JRSLE labelalign=left| Branch if signed lower or equal (S=1 or N≠V)
9000101101soff8align=left| JRM labelalign=left| Branch if interrupts masked (I=1)
00101110soff8align=left| JRSGE labelalign=left| Branch if signed greater or equal (N=V)
9000101110soff8align=left| JRIL labelalign=left| Branch if interrupt line is low
00101111soff8align=left| JRSLT labelalign=left| Branch if signed less than (N≠V)
9000101111soff8align=left| JRIH labelalign=left| Branch if interrupt line is high
colspan=12|
prefix || 0 ||colspan=3| mode ||colspan=4| opcode || operand ||colspan=2| One-operand instructions
0000colspan=4| opcodeaddr8align=left| OP (addr8,SP)align=left| Stack pointer relative
style="background:lightgrey;"

|

0001colspan=4| opcodecolspan=2| (reassigned to two-operand instructions with stack; see above)
style="background:lightgrey;"

|

0010colspan=4| opcodecolspan=2| (reassigned to conditional branches; see above)
0011colspan=4| opcodeaddr8align=left| OP addr8align=left| 8-bit absolute address
720011colspan=4| opcodeaddr16align=left| OP [addr16]align=left| 16-bit indirect address
920011colspan=4| opcodeaddr8align=left| OP [addr8]align=left| 8-bit indirect address of 16-bit address
0100colspan=4| opcodealign=left| OP Aalign=left| Accumulator
72/900100colspan=4| opcodeaddr16align=left| OP (addr16,X/Y)align=left| Indexed with 16-bit offset
—/900101colspan=4| opcodealign=left| OPW X/Yalign=left| X/Y register (16-bit operation)
720101colspan=4| opcodeaddr16align=left| OP addr16align=left| 16-bit address
—/900110colspan=4| opcodeaddr8align=left| OP (addr8,X/Y)align=left| 8-bit address plus X/Y
720110colspan=4| opcodeaddr16align=left| OP ([addr16],X)align=left| 16-bit indirect address plus X
92/910110colspan=4| opcodeaddr8align=left| OP ([addr8],X/Y)align=left| 8-bit indirect address plus X/Y
—/900111colspan=4| opcodealign=left| OP (X/Y)align=left| Indexed with no offset
colspan=12|
prefix0colspan=3| mode0000operandalign=left| NEG operandalign=left| Two's-complement negate
style="background:lightgrey;"

|

0colspan=3| mode0001colspan=2| (reassigned to exchange operations; see following section)
style="background:lightgrey;"

|

0colspan=3| mode0010colspan=2| (reassigned to other operations; see following section)
prefix0colspan=3| mode0011operandalign=left| CPL operandalign=left| Ones' complement, logical not
prefix0colspan=3| mode0100operandalign=left| SRL operandalign=left| Shift right logical, msbit cleared, lsbit to carry: (operand:C) := (0:operand)
style="background:lightgrey;"

|

0colspan=3| mode0101colspan=2| (reassigned to other operations; see following section)
prefix0colspan=3| mode0110operandalign=left| RRC operandalign=left| Rotate right through carry, (operand:C) := (C:operand)
prefix0colspan=3| mode0111operandalign=left| SRA operandalign=left| Shift right arithmetic, msbit preserved, lsbit to carry
prefix0colspan=3| mode1000operandalign=left| SLL operandalign=left| Shift left, msbit to carry: (C:operand) := (operand:0)
prefix0colspan=3| mode1001operandalign=left| RLC operandalign=left| Rotate left through carry, (C:operand) := (operand,C)
prefix0colspan=3| mode1010operandalign=left| DEC operandalign=left| Decrement; N and Z set, carry unaffected
style="background:lightgrey;"

|

0colspan=3| mode1011colspan=2| (reassigned to other operations; see following section)
prefix0colspan=3| mode1100operandalign=left| INC operandalign=left| Increment; N and Z set, carry unaffected
prefix0colspan=3| mode1101operandalign=left| TNZ operandalign=left| Test non-zero: set N and Z based on operand value
prefix0colspan=3| mode1110operandalign=left| SWAP operandalign=left| Swap halves of operand (4-bit rotate; 8-bit for SWAPW X and SWAPW Y)
prefix0colspan=3| mode1111operandalign=left| CLR operandalign=left| Set operand to 0, N cleared, Z set
colspan=12|
prefix || 0 ||colspan=3| mode ||colspan=4| opcode || operand ||colspan=2| Reassigned opodes [03-7][125B] from one-operand range
—/9000000001align=left| RRWA X/Yalign=left| Rotate word right through A: 8-bit right rotate of 24-bit concatenation of X/Y and A; (X:A) := (A:X)
00110001addr16align=left| EXG A,addr16align=left| Exchange A with memory
01000001align=left| EXG A,XLalign=left| Exchange A with X (low half)
01010001align=left| EXGW X,Yalign=left| Exchange X with Y (16 bits)
01100001align=left| EXG A,YLalign=left| Exchange A with Y (low half)
style="background:lightgrey;"

| —

01110001align=left colspan=2| (reserved)
colspan=12|
—/9000000010align=left| RLWA X/Yalign=left| Rotate word left through A: 8-bit left rotate of 24-bit concatenation of X/Y and A; (A:X) := (X:A)
00110010addr16align=left| POP addr16align=left| Pop from stack
—/9001000010align=left| MUL X/Y,Aalign=left| X/Y := XL/YL × A
01010010imm8align=left| SUBW SP,#immalign=left| SP := SP − imm8
—/9001100010align=left| DIV X/Y,Aalign=left| Divide X/Y by A; 16-bit quotient in X/Y, remainder in A
01110010align=left| PREFIXalign=left| Instruction prefix 72: modify following opcode
colspan=12|
style="background:lightgrey;"

|

00000101colspan=2 align=left| (reserved)
00110101imm8 addr16align=left| MOV addr16,#imm8align=left| Move immediate to memory (flags unaffected)
01000101addr8 addr8align=left| MOV addr8,addr8align=left| Move memory to memory (flags unaffected)
01010101addr16 addr16align=left| MOV addr16,addr16align=left| Move memory to memory (flags unaffected)
01100101align=left| DIVW X,Yalign=left| Divide X by Y (16 bits); quotient in X, remainder in Y
style="background:lightgrey;"

|

01110101colspan=2 align=left| (reserved)
colspan=12|
style="background:lightgrey;"

|

00001011colspan=2 align=left| (reserved)
00111011addr16align=left| PUSH addr16align=left| Push onto stack
01001011imm8align=left| PUSH #imm8align=left| Push onto stack
01011011imm8align=left| ADDW SP,#imm8align=left| SP := SP + imm8
01101011addr8align=left| LD (addr8,SP),Aalign=left| Store relative to stack
01111011addr8align=left| LD A,(addr8,SP)align=left| Load relative to stack
colspan=12|
— || 1 || 0 || 0 ||colspan=5| opcode || — ||colspan=2| Miscellaneous instructions. None implicitly set the condition codes.
10000000align=left| IRETalign=left| Return from interrupt (pop CC, A, X, Y, PC)
10000001align=left| RETalign=left| Pop 16-bit return address from stack to PC
10000010addr24align=left| INTalign=left| Special jump for interrupt vector table
10000011align=left| TRAPalign=left| Force trap interrupt
10000100align=left| POP Aalign=left| Pop A from stack
—/9010000101align=left| POPW X/Yalign=left| Pop X/Y from stack (16 bits)
10000110align=left| POP CCalign=left| Pop condition codes from stack
10000111align=left| RETFalign=left| Pop 24-bit return address from stack to PC
10001000align=left| PUSH Aalign=left| Push A onto stack
—/9010001001align=left| PUSHW X/Yalign=left| Push X/Y onto stack (16 bits)
10001010align=left| PUSH CCalign=left| Push condition codes onto stack
10001011align=left| BREAKalign=left| Stop for debugger if present, or NOP
10001100align=left| CCFalign=left| Complement (toggle) carry flag
10001101addr24align=left| CALLF addr24align=left| Push 24-bit PC; PC := addr24
9210001101addr16align=left| CALLF [addr16]align=left| Indirect far call; address is of 24-bit pointer
10001110align=left| HALTalign=left| Halt processor and clocks
10001111align=left| WFIalign=left| Wait for interrupt, halting processor but not clocks
7210001111align=left| WFEalign=left| Wait for event (coprocessor), handling interrupts normally while waiting
colspan=12|
10010000align=left| PDYalign=left| Instruction prefix 90: swap X and Y in next instruction
10010001align=left| PIYalign=left| Instruction prefix 91: PDY plus PIX
10010010align=left| PIXalign=left| Instruction prefix 92: use 8-bit memory indirect for operand
—/9010010011align=left| LDW X/Y,Y/Xalign=left| X/Y := Y/X
—/9010010100align=left| LDW SP,X/Yalign=left| SP := X/Y
—/9010010101align=left| LD XH/YH,Aalign=left| XH/YH := A
—/9010010110align=left| LDW X/Y,SPalign=left| X/Y := SP
—/9010010111align=left| LD XL/YL,Aalign=left| XL/YL := A
10011000align=left| RCFalign=left| Reset (clear) carry flag
10011001align=left| SCFalign=left| Set carry flag
10011010align=left| RIMalign=left| Reset interrupt mask (enable interrupts)
10011011align=left| SIMalign=left| Set interrupt mask (disable interrupts)
10011100align=left| RVFalign=left| Reset (clear) overflow flag
10011101align=left| NOPalign=left| No operation
—/9010011110align=left| LD A,XH/YHalign=left| A := XH/YH
—/9010011111align=left| LD A,XL/YLalign=left| A := XL/YL
colspan=12|
Prefix || 1 ||colspan=3| mode ||colspan=4| opcode || operand ||colspan=2| Two-operand instructions A := A op operand
style="background:lightgrey;"

| —

0000colspan=4| opcodeaddr8align=left| OP A,(addr8,SP)(opcodes 6, 7, C, D differ; see above)
style="background:lightgrey;"

| —

100colspan=5| opcodecolspan=2| (reassigned to miscellaneous instructions; see above)
1010colspan=4| opcodeimm8align=left| OP A,#imm8align=left| 8-bit immediate operand (forbidden as destination)
1011colspan=4| opcodeaddr8align=left| OP A,addr8align=left| 8-bit absolute address (forbidden for jump/call)
1100colspan=4| opcodeaddr16align=left| OP A,addr16align=left| 16-bit absolute address
721100colspan=4| opcodeaddr16align=left| OP A,[addr16]align=left| 16-bit indirect address
921100colspan=4| opcodeaddr8align=left| OP A,[addr8]align=left| 8-bit indirect address of 16-bit address
—/901101colspan=4| opcodeaddr16align=left| OP A,(addr16,X/Y)align=left| Indexed with 16-bit offset
721101colspan=4| opcodeaddr16align=left| OP A,([addr16],X)align=left| 16-bit indirect + X
92/911101colspan=4| opcodeaddr16align=left| OP A,([addr8],X/Y)align=left| 8-bit indirect + X/Y
—/901110colspan=4| opcodeaddr8align=left| OP A,(addr8,X/Y)align=left| Indexed with 8-bit offset
—/901111colspan=4| opcodealign=left| OP A,(X/Y)align=left| Indexed with no offset
colspan=12|
prefix1colspan=3| mode0000operandalign=left| SUB A,operandalign=left| A := A − operand
prefix1colspan=3| mode0001operandalign=left| CP A,operandalign=left| Compare A − operand
prefix1colspan=3| mode0010operandalign=left| SBC A,operandalign=left| A := A − operand − C subtract with borrow
prefix1colspan=3| mode0011operandalign=left| CPW X/Y,operandalign=left| Compare X/Y − operand (16 bit); compare Y/X if operand mode is indexed by X/Y (opcodes D3, E3, F3)
prefix1colspan=3| mode0100operandalign=left| AND A,operandalign=left| A := A & operand, bitwise and
prefix1colspan=3| mode0101operandalign=left| BCP A,operandalign=left| Bitwise test A & operand
prefix1colspan=3| mode0110operandalign=left| LD A,operandalign=left| A := operand
prefix1colspan=3| mode0111operandalign=left| LD operand,Aalign=left| Operand := A (mode 2 {{s|LD #imm8,A}} reassigned, see below)
prefix1colspan=3| mode1000operandalign=left| XOR A,operandalign=left| A := A ^ operand, exclusive-or
prefix1colspan=3| mode1001operandalign=left| ADC A,operandalign=left| A := A + operand + C, add with carry
prefix1colspan=3| mode1010operandalign=left| OR A,operandalign=left| A := A {{!}} operand, inclusive or
prefix1colspan=3| mode1011operandalign=left| ADD A,operandalign=left| A := A + operand
prefix1colspan=3| mode1100operandalign=left| JP operandalign=left| Low 16 bits of PC := operand, unconditional jump (modes 2 {{s|JP #imm8}} and 3 {{s|JP addr8}} reassigned, see below)
prefix1colspan=3| mode1101operandalign=left| CALL operandalign=left| Push 16-bit PC, low 16 bits of PC := operand (modes 2 {{s|CALL #imm8}} and 3 {{s|CALL addr8}} reassigned, see below)
prefix1colspan=3| mode1110operandalign=left| LDW X/Y,operandalign=left| Load X/Y := operand; use 16 instead of 90 1E for LDW Y,(addr8,SP)
prefix1colspan=3| mode1111operandalign=left| LDW operand,X/Yalign=left| Operand := X/Y (16-bit, mode 2 {{s|LD #imm8,X}} reassigned, see below); store Y/X if operand mode is indexed by X/Y (opcodes DF, EF, FF); use 17 instead of 90 1F for LDW (addr8,SP),Y
colspan=12|
Prefix || 1 ||colspan=3| mode ||colspan=4| opcode || operand ||colspan=2| Reassigned opcodes A7, AC, BC, AD, BD, AF from two-operand range
—/9010100111addr24align=left| LDF (addr24,X/Y),Aalign=left| Load far (={{s|LD #imm8,A}})
92/9110100111addr16align=left| LDF ([addr16],X/Y),Aalign=left| 16-bit address of 24-bit pointer
10101100addr24align=left| JPF addr24align=left| PC := addr24 (={{s|JP #imm8}})
9210101100addr16align=left| JPF [addr16]align=left| Indirect far jump; address is of 24-bit pointer
10111100addr24align=left| LDF A,addr24align=left| Load far (={{s|JP addr8}})
9210111100addr16align=left| LDF A,[addr16]align=left| Load far, 16-bit address of 24-bit pointer
10101101soff8align=left| CALLR labelalign=left| Push 16-bit PC, PC := PC + operand (={{s|CALL #imm8}})
10111101addr24align=left| LDF addr24,Aalign=left| Operand := A (={{s|CALL addr8}})
9210111101addr16align=left| LDF [addr16],Aalign=left| Operand := A, 16-bit address of 24-bit pointer
—/9010101111addr24align=left| LDF A,(addr24,X/Y)align=left| Load far (={{s|LDW #imm8,X}})
92/9110101111addr16align=left| LDF A,([addr16],X/Y)align=left| 16-bit address of 24-bit pointer
colspan=12|
72 || 1 ||colspan=3| mode ||colspan=4| opcode || operand ||colspan=2| Index register arithmetic (16-bit) X/Y := X/Y ± operand
721010colspan=4| opcodeimm16align=left| OPW X/Y,#imm16align=left| 16-bit immediate
721011colspan=4| opcodeaddr16align=left| OPW X/Y,addr16align=left| 16-bit absolute
721111colspan=4| opcodeaddr8align=left| OPW X/Y,(addr8,SP)align=left| Stack-relative
721colspan=3| mode0000operandalign=left| SUBW X,operandalign=left| X := X − operand (prefer opcode 1D for SUBW X,#imm16)
721colspan=3| mode0010operandalign=left| SUBW Y,operandalign=left| Y := Y − operand
721colspan=3| mode1001operandalign=left| ADDW Y,operandalign=left| Y := Y + operand
721colspan=3| mode1011operandalign=left| ADDW X,operandalign=left| 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 a 90 prefix exchanges X and Y so the register is X and the addressing mode is indexed by Y.

References

{{Reflist}}