Stack Option

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.

Table 1. Stack Suboptions
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).

Note: Use the 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.