3.11.3 Naked Functions
Keywords: sdccman

##
3.11.3 Naked Functions

A special keyword may be associated with a function declaring it as __naked. The _naked function modifier attribute prevents the compiler from generating prologue and epilogue code for that function. This means that the user is entirely responsible for such things as saving any registers that may need to be preserved, selecting the proper register bank, generating the return instruction at the end, etc. Practically, this means that the contents of the function must be written in inline assembler. This is particularly useful for interrupt functions, which can have a large (and often unnecessary) prologue/epilogue. For example, compare the code generated by these two functions:

> volatile data unsigned char counter;
> void simpleInterrupt(void) __interrupt (1)
> {
> counter++;
> }
> void nakedInterrupt(void) __interrupt (2) __naked
> {
> __asm
> inc _counter ; does not change flags, no need to save psw
> reti ; MUST explicitly include ret or reti in _naked function.
> __endasm;
> }

For an 8051 target, the generated simpleInterrupt looks like:

> Note, this is an outdated example, recent versions of SDCC generate
> the same code for simpleInterrupt() and nakedInterrupt()!
> _simpleInterrupt:
> push acc
> push b
> push dpl
> push dph
> push psw
> mov psw,#0x00
> inc _counter
> pop psw
> pop dph
> pop dpl
> pop b
> pop acc
> reti

whereas nakedInterrupt looks like:

> _nakedInterrupt:
> inc _counter ; does not change flags, no need to save psw
> reti ; MUST explicitly include ret or reti in _naked function

The related directive #pragma exclude allows a more fine grained control over pushing & popping the registers.

While there is nothing preventing you from writing C code inside a _naked function, there are many ways to shoot yourself in the foot doing this, and it is recommended that you stick to inline assembler.