4.6.1.24 Stack Option
The
-mstack=model[:size|auto]
option
selects the default stack model to be used by a program, which will dictate which stack
will be used for functions that do not use a stack specifier. Additionally, it can specify
the size of memory reserved for the software stack.
Functions can use stack specifiers (described in Reentrant And Nonreentrant
Specifiers) to indicate which
stack should be used for that function's stack-based variables. For functions that do not
use these specifiers, the -mstack
option controls the stack type that the
compiler will use.
The two data stacks available are called a compiled stack and a software stack. Objects destined for the software stack might be allocated to working registers in a register-optimized reentrant stack (if that feature is enabled, see Rors Option) at the compiler's discretion, but still fall under the software stack model. See Data Stacks for more information on storage of stack-based objects. The stack models that can be used with this option are described in the table below.
Model | Default Allocation for Stack-based Variables |
---|---|
compiled or
nonreentrant | Use the compiled stack for all functions not using a stack specifier; these functions will then be non-reentrant. |
software or
reentrant | Use the software and/or register-optimized reentrant stack for functions not using a stack specifier; these functions will then be reentrant. |
hybrid | For functions not using a stack specifier, choose a stack type based on how that function is called and referenced in the program. |
If the -mstack
option is not used, all functions not
using a stack specifier will use the compiled stack and be non-reentrant.
The software
(or reentrant
) or hybrid
models have no effect on projects targeting baseline and mid-range devices, as these
devices only support a compiled stack. Interrupt functions might save context to the
software stack when using the hybrid or reentrant models, however they will must the
compiled stack for autos they define. Functions called by an interrupt function may use the
software stack.
The hybrid model (-mstack=hybrid
) will let the compiler
choose how to encode each function based on how it is called. See Automatic Storage Duration Objects for more information on
what factors the compiler considers when making this choice. This model allows for
reentrancy, when required, but takes advantage of the efficiency of the compiled stack for
the majority of the program’s functions.
software
(reentrant
) setting with caution. The maximum runtime size of the
software stack is not accurately known at compile time, so the compiler cannot predict an
overflow, which could corrupt objects or registers. When all functions are forced to use
the software stack, the stack size might increase substantially. Code to access objects on
a software stack is typically larger than that used to access objects on a compiled
stack.In addition to the stack model, the -mstack
option can be
used to specify the maximum size of memory reserved by the compiler for the software stack.
This option configuration only affects the conventional software stack; it does not affect
the number or allocation of working registers in the register-optimized reentrant stack.
Nor can this form of the option be used to change the amount of available memory for the
compiled stack, which is fixed and known at compile time.
Distinct software stacks are created for use by main-line code and
interrupt functions, but this is transparent at the program level. In the case of PIC18
devices, separate stacks are created for high- and low-priority interrupts (along with one
for main-line code), each interrupt stack available for all interrupt functions associated
with an interrupt source set to that priority. So, for example, if you are using a PIC18
device with the vectored interrupt controller enabled, each reentrant interrupt function
defined using the __high_priority
keyword will use the software stack
devoted to high-priority interrupts. The compiler automatically manages the allocation of
memory to each stack. If your program does not define any interrupt functions, all the
available memory can potentially be made available to the software stack used by main-line
code.
reentrant
stack type with a
colon-separated list of decimal values, each being the size, in bytes, of the memory to be
reserved. The sizes specified in the option correspond in this order to: the main-line
code, the low-priority interrupt and the high-priority interrupt. For example the
option:-mstack=reentrant:200:0:40
when used with PIC18 projects will
attempt to reserve 200 bytes for the main-line stack, zero bytes for the low-priority
interrupt stack, and 40 bytes for the high-priority interrupt stack. At runtime, the stacks
will be able to grow to the specified sizes with no corruption of data. This memory is
reserved unconditionally, even if no reentrant functions are present in the program.auto
, in which case
the compiler will calculate a maximum size for this stack after other static, stack, and
heap allocations have been made. Memory with this calculated size will only be reserved,
however, if the compiler detects the presence of any function using a reentrant stack. If
no -mstack
option is specified, then the compiler uses an auto setting for
every stack that can be potentially used by the program. Whenever acting with an auto stack
size setting, the compiler will issue a compiler advisory message if reentrant functions
have been detected and memory has been reserved as a result. For PIC18 devices, the
following example:-mstack=reentrant:auto:30:50
will
arrange the stack starting locations so that the low-priority interrupt stack can grow to
at most 30 bytes (before overflow); the high-priority interrupt stack can grow to at most
50 bytes (before overflow); and the main-line code stack can consume the remainder of the
free memory after other static, stack, and heap allocations have been made. If you are not
using an interrupt, it is recommended that you explicitly set the unused interrupt stack
size to zero using this option.If the maximum stack sizes are specified with this option, each size must
be a numerical value or the auto
token; do not leave a size field empty.
If the sizes specified in this option would allocate more stack memory than is available, a
warning will be issued and only the available memory will be utilized.
The size of the heap used by dynamic memory allocation functions is also dynamic in nature,
and memory must be reserved for its use. That memory is specified using the
-mheap
option (see Heap Option). A size argument of
auto
can be used with both the -mstack
and
-mheap
options, in which case the compiler will evenly distribute the
free memory remaining between the heap and stacks after statically allocated objects have
been placed.