Close

SDCC MCU oriented features worth noting

A project log for 8051 tuner

A 3-octave tone generator using an 8051 MCU

ken-yapKen Yap 12/21/2018 at 00:230 Comments

1. On the MCS-51 Harvard architecture, SDCC implements __code space, which is where constants and constant strings should be stored. The declarations:

__code unsigned const short divisors[] = {
    ...
};
__code const char *const descriptions[] = {
    ...
};

and the correct use of const ensures that these constant data are stored in code memory (ROM). The appropriate MOVC instructions are generated when copying from these areas.

But also read the SDCC manual about different types of pointers. When pointing to __code data the use of a __code pointer will generate better code and take less bytes than a generic pointer.

AVR C/C++, e.g. Arduino, has a similar feature for constant data in code memory: PROGMEM.

2. SDCC supports __naked functions which are good for short pieces of code that don't use any registers, e.g. operate on ports, so you can avoid register save and restore.

3. SDCC supports interrupt service routines (ISRs). It will generate a reti instead of the normal ret for returns. It will do the appropriate register save and restore. With the __using() pragma, you can direct it to use an alternate register set.

4. The idiom:

P1_4 ^= 1;      // flip LED

is the shortest way to flip a port or low memory bit. It generates one instruction, i.e.:

cpl P1_4

 5. SDCC is smart enough to do tail call optimisation. For example, one of the I2C routines ends thus:

delay5us();

Instead of generating a lcall _delay5us followed by a ret, it generates a ljmp _delay5us, which then returns directly to the caller, saving a few bytes and a bit of time. But it has to know that delay5us() has certain properties.

6. Not specific to SDCC but inline generates code at the point of use instead of a function call (and a function body elsewhere) where the trade-off, e.g. for small functions, is worthwhile

Discussions