Reputation: 2322
Building on my last question i'm trying to figure out how .local
and .comm
directives work exactly and in particular how they affect linkage and duration in C.
So I've run the following experiment:
static int value;
which produces the following assembly code (using gcc):
.local value
.comm value,4,4
When initialized to zero yields the same assembly code (using gcc):
.local value
.comm value,4,4
This sounds logical because in both cases i would expect that the variable will be stored in the bss segment. Moreover, after investigating using ld --verbose
it looks that all .comm
variables are indeed placed in the bss segment:
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
// ...
}
When i initialize however my variable to a value other than zero, the compiler defines the variable in the data segment as i would expected, but produces the following output:
.data
.align 4
.type value, @object
.size value, 4
value:
.long 1
Besides the different segments (bss and data respectively) which thanks to your help previously i now understand, my variable has been defined as .local
and .comm
in the first example but not in the second. Could anyone explain that difference between the two outputs produced from each case?
Upvotes: 2
Views: 821
Reputation: 157484
The .local
directive marks a symbol as a local, non-externally-visible symbol, and creates it if it doesn't already exist. It's necessary for 0-initialized local symbols, because .comm
declares but does not define symbols. For the 1-initialized variant, the symbol itself (value:
) declares the symbol.
Using .local
and .comm
is essentially a bit of a hack (or at least a shorthand); the alternative would be to place the symbol into .bss
explicitly:
.bss
.align 4
.type value, @object
.size value, 4
value:
.zero 4
Upvotes: 1
Reputation: 5083
Linux kernel zeros the virtual memory of a process after allocation due to security reasons. So, the compiler already knows that the memory will be filled with zeros and does an optimization: if some variable is initialized to 0, there's no need to keep space for it in a executable file (.data
section actually takes some space in ELF executable, whereas .bss
section stores only its length assuming that its initial contents will be zeros).
Upvotes: 1