There is some variation in the above section names but with ARM32 GCC, statics are categorised thus:
int fred; goes into BSS (uninitialised data, used to go into COMMON in GCC versions before v10, now it is better because BSS gets zeroed)
int fred=0; goes into BSS (which by definition is zeroed by startup code)
int fred=1; goes into DATA (statics initialised to nonzero, copied to RAM at start)
int Fred; declared at file scope has static storage duration. Regardless of internal (if static is used) or external linkage (if not), and where the compiler decides to put it, it is NOT uninitialized data and never was for any vaguely standard compliant compiler.
There is no such thing in C for static duration objects, if an initializer is not provided, it is as if =0 (or equivalent for aggregates) was written.
Chapter and verse of the standard on request.No request, but I am (sometimes) a pedant.
However, IME on the arm32, RAM resident stuff doesn't run faster than FLASH resident stuff - probably because the code cache works so well, being loaded 128 bytes at a time. I found delay loops run 20% faster from FLASH than in RAM resident code.
This is an overgeneralization, might be true for your specific MCU (STM32F4xx, IIRC) but absolutely not true in general.
EtA: Now I am at real keyboard:
Proof of initialization to 0Standard ref, C11 but unchanged since, like, forever: 6.7.9 Initialization, §10:
[...]If an object that has static or thread storage duration is not initialized explicitly, then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;
— if it is a union, the first named member is initialized (recursively) according to these rules, and any padding is initialized to zero bits;