I want to learn about elf files, but when I think of global variables, global static variables and scope static variables, I have some confusion. For example:
In general, the data segment of the executable contains initialized global/static variables and the BSS segment contains uninitialized global/static variables.
When the loader loads your program into memory, the unitialized global/static variables are automatically zero-filled.
In C, static variables (initialized or not) inside a function just mean the variables have local/function scope (sometimes referred to as internal static), but they still live in the Data/BSS segments depending on whether or not they are initialized.
So regardless of how many times fun() gets called, the static variables are initilized only once when the program is loaded.
Variables defined as static and outside any functions still live in either the data or bss segments, but have file scope only.
When your code is compiled, there is an import and export list that is part of each object file and is used by the linkage editor. Your static variables will not be in the export list and therefore inaccessable to other object files.
By excluding the static keyword, your global variables are placed in the export list and can be referred to by other object modules and the linkage editor will be able to find the symbols when creating the executable.
For a pictoral view:
+--------- TEXT ---------+ Low memory
| main() |
| fun() |
+--------- DATA ---------+
| int a (global scope) |
| int c (file scope) |
| int e (function scope) |
+---------- BSS ---------+
| int b (global scope) |
| int d (file scope) |
| int f (function scope) |
+------------------------+