2012-01-04 10 views
20

Wszystkie zainicjalizowane zmienne globalne/statyczne zostaną przeniesione do sekcji danych inicjowanych :. Wszystkie niezainicjowane zmienne globalne/statyczne zostaną przeniesione do niezainicjowanych sekcji danych (BSS). Zmienne w BSS otrzymają wartość 0 podczas czasu ładowania programu.Jeśli zmienna globalna zostanie zainicjowana na 0, czy przejdzie do BSS?

Jeśli zmienna globalna jest jawnie zainicjowana na zero (int myglobal = 0), gdzie ta zmienna zostanie zapisana?

+4

Co się stało ens, kiedy go wypróbujesz? Możesz zobaczyć, co znajduje się w pliku '.o', używając' objdump -x'. –

+0

Próbowałem poniżej A). Dla int globalvar = 0; objdump -x test> 1.txt B) .for ==> int globalvar; objdump -x testu> 2.txt A diff: - 2 .bss 00000004 00000000 00000000 00000058 2 ** 2 + 2 .bss 00000000 00000000 00000000 00000058 2 ** 2 -00000000 g o.bss 00000004 globalvar +00000004 O * COM * 00000004 globalvar –

+0

@LunarMushrooms Update post * ahem * :) –

Odpowiedz

26

Kompilator może umieścić taką zmienną w bss, a także w data. Na przykład, GCC ma special option kontroli takiego zachowania:

-fno-zero-initialized-in-bss

Jeśli cel wspiera sekcję BSS, GCC domyślnie umieszcza zmienne, które są inicjowane na zero w BSS. Ten może zaoszczędzić miejsce w wynikowym kodzie. Ta opcja wyłącza to zachowanie , ponieważ niektóre programy jawnie polegają na zmiennych przechodzących do sekcji danych. Np., Aby wynikowy plik wykonywalny mógł znaleźć początek tej sekcji i/lub dokonać w oparciu o to założeń. Domyślne ustawienie to -fzero-initialized-in-bss.

Próbowałem z poniższym przykładzie (test.c pliku):

int put_me_somewhere = 0; 

int main(int argc, char* argv[]) { return 0; } 

Kompilacja bez opcji (domyślnie -fzero-initialized-in-bss):

$ touch test.c && make test && objdump -x test | grep put_me_somewhere 
cc  test.c -o test 
0000000000601028 g  O .bss 0000000000000004    put_me_somewhere 

kompilacji z -fno-zero-initialized-in-bss opcji:

$ touch test.c && make test CFLAGS=-fno-zero-initialized-in-bss && objdump -x test | grep put_me_somewhere 
cc -fno-zero-initialized-in-bss test.c -o test 
0000000000601018 g  O .data 0000000000000004    put_me_somewhere 
+1

Ciekawa reputacja, masz. –

+1

@EknathIyer Zepsułem to :( –

+0

dayummm, szkoda, Eldar –

6

Jest to dość łatwe do sprawdzenia dla konkretnego kompilatora:

$ cat bss.c 
int global_no_value; 
int global_initialized = 0; 

int main(int argc, char* argv[]) { 
    return 0; 
} 
$ make bss 
cc  bss.c -o bss 
$ readelf -s bss | grep global_ 
    32: 0000000000400420  0 FUNC LOCAL DEFAULT 13 __do_global_dtors_aux 
    40: 0000000000400570  0 FUNC LOCAL DEFAULT 13 __do_global_ctors_aux 
    55: 0000000000601028  4 OBJECT GLOBAL DEFAULT 25 global_initialized 
    60: 000000000060102c  4 OBJECT GLOBAL DEFAULT 25 global_no_value 

szukamy lokalizacji 0000000000601028 i 000000000060102c:

$ readelf -S bss 
There are 30 section headers, starting at offset 0x1170: 

Section Headers: 
    [Nr] Name    Type    Address   Offset 
     Size    EntSize   Flags Link Info Align 
... 
    [24] .data    PROGBITS   0000000000601008 00001008 
     0000000000000010 0000000000000000 WA  0  0  8 
    [25] .bss    NOBITS   0000000000601018 00001018 
     0000000000000018 0000000000000000 WA  0  0  8 

Wygląda na to obie wartości są przechowywane w .bss sekcja w moim systemie: gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4).

1

Zachowanie zależy od implementacji języka C. Może się on skończyć w .data lub .bss, a także w celu zwiększenia zmian, w których nie kończy się .data zajmująca nadmiarowy obszar, lepiej nie inicjować go jawnie na 0, ponieważ będzie on ustawiony na 0, jeśli obiekt ma statyczny czas trwania.

+0

To pytanie jest oznaczone GCC (chociaż wersja/cel nie została określona). –