where are constant variables stored in microcontroller?

If you were writing assembler, you would decide which locations are used to hold which constants or variables, through org or similar directives.

When you are writing C, the C tool chain you're using will store stuff where it's been programmed to. Variables obviously tend to go in RAM, constants can go in either RAM or Flash, program tends to go in Flash.

It's all down to how the tool for that particular target processor has been designed, where it gets its instruction from where to put stuff. It might all be baked into the code, in which case you don't get any say, it goes where the tool chain's creators chose to send it. It may take directives from somewhere (source code, command line, make file, environmental variable) so that you can rebase stuff.

Read your specific documentation. It's not physics, it's all down to the whim of man.


The answer to your question is specific to the particularly architecture you are using. Since you have mentioned ARM, I'll give you an answer based on this.

The ARM Cortex is a register based design, so basically any operands (const or not) must some how make their way into one of the internal registers before they can be used by program instructions. This is central to answering your question, because there are a couple of different ways the architecture allows this to be done.

For small constants (typically less than 8 or 10-bits), the value can be encoded directly into certain instructions. For example, there is an ADD #imm instruction that will add a 12-bit value encoded into the instruction word to a register. This can be used to directly specify a constant in your program. If you were adding the same constant in various different places in your code, and the value was 12-bits or less, then the compiler would just use an ADD #imm instruction everywhere your constant was required. In other words, the actual const will be replicated in multiple locations throughout the code that is stored in FLASH.

If the constant is large then this won't work, so the value will have to be stored in its own dedicated FLASH memory location. The chip has another instruction, called LDR which it uses to move a value from a memory location into the internal registers where it can be used. This instruction does not care whether the value is physically stored in FLASH or RAM, it just pulls the value from a specific address in memory and puts it into a register. Note that compared to the situation with small constants, this requires an extra instruction cycle, but if the constant is used repeatedly in a block of code then the compiler will cache it by putting it into a spare register if one is available.

However now we run into a potential problem. On most Cortex chips the FLASH memory runs at the same speed or slower than the CPU core. If we attempt to execute an LDR instruction from a FLASH location, this read operation of the physical memory must compete with the reading of the next instruction. This creates a bottleneck, which causes the CPU to have to stall until the data has been read. Even worse, on many implementations, the FLASH runs very slow and a pipeline cache is used to feed instructions to the CPU faster. In these devices reading, say, a table of constant values can expose the fundamental FLASH access bottleneck causing severe loss of performance.

For this reason, many compilers will look to copy any constant data into spare RAM locations if possible. This will prevent such issues, and since RAM is normally faster to access than FLASH can prevent a lot of performance bottlenecks. If there is unused RAM in your program anyway, then it is virtually no overhead for the compiler to do this.

So there is most definitely a logic to how the compiler allocates constant data to physical memory, but thankfully in most situations the chip and compiler designers have done all this hard work for you, and you can just trust that it is doing whatever is best for your particular code and optimization level.


The link you provided explains what happens on regular computers, which load everything (including code) in RAM, anyway (because this is the only thing available, but there is plenty of it). It doesn't apply to embedded programming, where you also have flash available. So, if you use a linker script appropriate for embedded programming (which should be the default for embedded IDEs), constant data actually end up in flash, as it should.

Now, if you use macro definitions, it is completely different. Macros are replaced within the source code by the preprocessor, which means that the constant will be recompiled independently each time you use it in your code. And, if you use it multiple times, indeed, the code will be bigger. This, of course, shouldn't be the case for simple integer constants. For string constants, good compilers will try to merge multiple identical values to reduce this effect and keep size small, but this is not guaranteed, and may depend whether the strings are only used within the same compilation unit (.c source file) or across multiple comilation units. For constant structures/objects, the compilers usually don't do much optimization.

Answers would be more relevant to your specific case if you provided extracts of your source code, and indicate which compiler/IDE you're using.