Next Previous Contents

8. Parameters & Local Variables

Automatic (local) variables and parameters to functions can either be placed on the stack or in data-space. The default action of the compiler is to place these variables in the internal RAM ( for small model) or external RAM (for Large model). They can be placed on the stack either by using the --stack-auto compiler option or by using the 'reentrant' keyword in the function declaration.

eg

unsigned short foo( short i) reentrant { 
... 
}
 

Note that when the parameters & local variables are declared in the internal/external ram the functions are non-reentrant. Since stack space on 8051 is limited the 'reentrant' keyword or the --stack-auto option should be used sparingly. Note the reentrant keyword just means that the parameters & local variables will be allocated to the stack, it DOES NOT mean that the function is register bank independent.

When compiled with the default option (i.e. non-reentrant ), local variables can be assigned storage classes and absolute addresses.

eg

unsigned short foo() { 
   xdata unsigned short i; 
   bit bvar; 
 
  data at 0x31 unsiged short j; 
... 
}
 

In the above example the variable i will be allocated in the external ram, bvar in bit addressable space and j in internal ram. When compiled with the --stack-auto or when a function is declared as 'reentrant' local variables cannot be assigned storage classes or absolute addresses.

Parameters however are not allowed any storage class, (storage classes for parameters will be ignored), their allocation is governed by the memory model in use , and the reentrancy options.

8.1 Overlaying

For non-reentrant functions SDCC will try to reduce internal ram space usage by overlaying parameters and local variables of a function (if possible). Parameters and local variables of a function will be allocated to an overlayable segment if the function has no other function calls and the function is non-reentrant and the memory model is small. If an explicit storage class is specified for a local variable , it will NOT be overplayed.

Note that the compiler (not the linkage editor) makes the decision for overlaying the data items. Functions that are called from an interrupt service routine should be preceded by a #pragma NOOVERLAY if they are not reentrant Along the same lines the compiler does not do any processing with the inline assembler code so the compiler might incorrectly assign local variables and parameters of a function into the overlay segment if the only function call from a function is from inline assembler code, it is safe to use the #pragma NOOVERLAY for functions which call other functions using inline assembler code.

Parameters and Local variables of functions that contain 16 or 32 bit multiplication or division will NOT be overlayed since these are implemented using external functions.

eg.

#pragma SAVE 
#pragma NOOVERLAY 
void set_error( unsigned short
 errcd) 
{ 
    P3 = errcd; 
} 
#pragma RESTORE 
void some_isr
 () interrupt 2 using 1 
{ 
    ... 
    set_error(10); 
    ... 
}
 

In the above example the parameter errcd for the function set_error would be assigned to the overlayable segment (if the #pragma NOOVERLAY was not present) , this could cause unpredictable runtime behavior. The pragma NOOVERLAY ensures that the parameters and local variables for the function are NOT overlayed.


Next Previous Contents