2009-08-11 14 views
8

Podczas nauki przydarzyło mi się trochę problemów. Wiem, że niezainicjowane zmienne globalne w C są przypisane do sekcji .bss w pliku wykonywalnego ELF. Ale co się z nimi stanie, kiedy zacznę ich używać? tj. czy dostają miejsce na kupie lub gdzieś indziej?Gdzie są niezainicjowane zmienne globalne po uruchomieniu?

Próbowałem dowiedzieć się, drukując adres (wciąż niezainicjowane) zmiennej globalnej z

printf("%x",&glbl); 

który zawsze zwraca tę samą wartość 0x80495bc ... Dlaczego?

+1

Zauważyłem, że zaakceptowałeś odpowiedź 5 minut po zadaniu pytania. Otrzymasz więcej odpowiedzi, jeśli pozostawisz to otwarte przez jakiś czas, ponieważ ludzie będą bardziej zmotywowani do poprawy odpowiedzi. – Adriaan

+0

Dzięki za podpowiedź, na pewno zrobię to następnym razem. – Patrick

Odpowiedz

8

Kiedy system operacyjny ładuje twój program, alokuje wystarczającą ilość pamięci z przestrzeni adresowej twojego programu, aby przechowywać wszystko w sekcji .bss i zeruje całą tę pamięć. Kiedy przypisujesz lub odczytujesz adres lub wprowadzasz jego adres, manipulujesz tą pamięcią, która została przydzielona, ​​aby zapewnić pamięć dla sekcji .bss.

+0

Ah i to również wyjaśnia, dlaczego wartość zawarta niezainicjowanej zmiennej globalnej była zawsze równa zero. Dzięki! – Patrick

+0

Niektóre kompilatory/architektury obsługują sekcję SBSS dla małych danych. Często odbywa się to jako optymalizacja, dzięki czemu dane mogą być pobierane poprzez indeksowanie od początku sekcji SBSS. Można to często zrobić za pomocą rejestru gp i 16-bitowego indeksowania – zebrabox

2

Zmienne globalne zawsze otrzymują pamięć statyczną, jeśli nie są zainicjalizowane, nie mają miejsca w pliku binarnym, ale przechodzą do pamięci, gdy plik binarny jest załadowany do przestrzeni pamięci procesowej.

1

BSS jest symbolem zastępczym zdefiniowanym w pliku wykonywalnym (lub ELF). Nie zajmuje więc miejsca na dysku, a jedynie określa, jaki region pamięci powinien zostać przydzielony przez łącznik lub program ładujący.

Dokładna operacja zależy od systemu operacyjnego. Ponieważ odwołujesz się do ELF, zakładam, że jest on przeznaczony do użytku w systemie wbudowanym. Jeśli tworzysz kod ROMmable, twój plik cmd linkera zmapuje BSS do statycznego regionu adresu.

W przypadku kompilacji dla systemu operacyjnego (tj. Systemu Linux) program ładujący z systemu operacyjnego wykona przesiadkę, w której mapuje wszystkie lokalizacje oznaczone jako względne w formacie możliwym do wykonania na fizyczne lub logiczne lokalizacje w pamięci.

Ponieważ wspominasz, zawsze widząc tę ​​samą wartość, oznacza to, że proces jest powtarzalny dla twojego systemu. Można spodziewać się zmian, gdy zmienisz pliki łącznika (tj. Regiony adresowe), kolejność łączy (tj. Moduły otrzymają przydzielone miejsce w innej kolejności) lub system operacyjny.

Nawet jeśli korzystasz z wartości BSS, adres pozostanie taki sam dla procesu, który uruchomisz.

1

Ta sekcja BSS otrzymuje blok pamięci w przestrzeni adresowej procesu, podobnie jak kod i sekcje stosu (i wszelkie inne ELF mogą mieć). Kiedy już się tam znajdą, nie mają już żadnego adresu IP. Program ładujący porządkuje rzeczy, a następnie wywołuje punkt wejścia procesu.

Powiązane problemy