STM8-Support only started with Version 3.4 in Ubuntu 14.10. For Ubuntu 14.4:

    add-apt-repository ppa:laczik/ppa
    apt-get update
    apt-get install sdcc

But even this version is fairly old and contains some known bugs. Better download a current snapshot build from and unpack it to /opt/sdcc. This requires a current version of libstdc++6:

    add-apt-repository ppa:ubuntu-toolchain-r/test
    apt-get update
    apt-get install libstdc++6

If you prefer to compile stm8flash yourself instead of using the Linux binaries in the tools directory:

    git clone
    cd stm8flash
    sudo make install

Download some example code:

    git clone
    cd sdcc-examples-stm8

The examples are meant for the STM8L, not the STM8S. This requires some changes to account for the different pinout and register addresses (see below). Finally upload the binary to the CPU:

    stm8flash -c stlinkv2 -p stm8s103?3 -w blinky.ihx

Mixing assembler code with C code


stacktest(0x1234, 0x5678);


push    #0x78
push    #0x56
push    #0x34
push    #0x12
call    _stacktest

resulting stack content (starting at [SP], using simulator sstm8):

0> dch 0x17f9
0x017f9 c0 80 ab 12 34 56 78 5b ....4Vx[

=> first paramter starts at [SP+3], MSB first.

Register assignment

return values: 8 bit values in A, 16 bit values in X, 32 bit values in Y/X (Y=MSB, X=LSB)

register preservation: Not implemented for the STM8 (yet?). For some architectures SDCC implements the possibility to mark a function that it does not effect the contents of some registers:

void f(void) __preserves_regs(b, c, iyl, iyh);

Direct memory access

To access a memory location without using a pointer variable it is possible to do things like this:

#define ODR (*((unsigned char *)0x5005))
#define bitSet(value, bit) ((value) |= (1 << (bit)))

void main()

  bitSet(ODR, 3);

  *((unsigned char *) 0x5005) |= 4;

Notes on SDCC

The linker sdld does not automatically link the object file for main.c if it is part of a library. It must be part of the list of object files. (Important for the build process with

Befehl __critical{..} sollte eigentlich den vorherigen Interrupt-Zustand wiederherstellen, es wird aber einfach ein festes Paar sim/rim produziert. Mit "push cc; sim" und "pop cc" klappt es im Simulator, aber nicht in der Realität.

Für jeden benutzten Interrupt muss ein Prototyp in der Datei stehen, in der auch main() definiert ist. Aber für jeden Prototypen, für den es keine Funktion gibt, ergibt einen Linkerfehler. Das erklärt den Sinn von stm8s_it.h im Projektverzeichniss. Eine Arduino-ähnliche Umgebung muss diese Datei also nach Analyse aller Sourcen selber erzeugen.

Simulator sstm8

Has improved a lot recently. The UART and timer part is usable now (as of rev. 9998) and the subtle differences in the memory layout of the I/O section for the different cpu subtypes are factored in.

Make sure to use a recent snapshot build if you are planing to use simulator!

Missing peephole optimisations

See discussion of issue #14

Missing compiler features