The -mstack=model[:size]
option allows
selection of the stack model to be used by a program’s stack-based variables.
The data stacks available are called a compiled stack and a software stack (described in Data Stacks). 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; functions are non-reentrant (default). |
software or
reentrant |
Use the software stack for eligible functions and devices; such functions are reentrant. |
hybrid |
Use the compiled stack for functions not called reentrantly; use the software stack for all other eligible functions and devices; functions are only reentrant if required. |
The software
(or reentrant
) or
hybrid
models have no effect on projects targeting baseline and
mid-range devices, as they only support a compiled stack. In addition, all interrupt
functions for any device must use the compiled stack, but functions they call 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. A function is compiled to use
the software stack if it is called reentrantly in the program; otherwise, it will use a
compiled stack. 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.
This option setting can be overridden for individual functions by using function specifiers (described in Reentrant And Nonreentrant Specifiers).
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.In addition to the stack model, this 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 software stack; there are no controls for the size of the compiled stack.
Distinct memory areas are allocated for the software stack that is used by main-line code and each interrupt function, but this is transparent at the program level. The compiler automatically manages the allocation of memory to each stack. If your program does not define any interrupt functions, all the available memory is made available to the software stack used by main-line code.
You can manually specify the maximum space allocated for each area of the
stack by following the stack type with a colon-separated list of decimal values, each value
being the maximum size, in bytes, of the memory to be reserved. The sizes specified
correspond to the main-line code, the lowest priority interrupt through the highest
priority interrupt. (PIC18 devices have two separate interrupts; other devices have only
one.) Alternatively, you can explicitly state that you have no size preference by using a
size of auto
. 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 that can be allocated to the stack (before overflow). If you are compiling for a PIC18 device and only one interrupt is used, it is recommended that you explicitly set the unused interrupt stack size to zero using this option.
If you do specify the stack sizes using this option, each size must be
specified numerically or you can use the auto
token. Do not leave a size
field empty. If you try to use this option to allocate more stack memory than is available,
a warning is issued and only the available memory will be utilized.