To zależy. Program posiada kilka stałych:
int a = 5;
jest to „statyczna” inicjalizacji (który pojawia się, gdy tekst programu i dane są ładowane przed biegania). Wartość jest przechowywana w pamięci zarezerwowanej przez a
, która znajduje się w "sekcji programu" do odczytu i zapisu. Jeśli coś zmieni się na a
, wartość 5 zostanie utracona.
int b=5;
Jest to zmienna lokalna z ograniczonym zakresem (tylko przez main()
). Magazyn może być rejestrem CPU lub lokalizacją na stosie. Instrukcje generowane dla większości architektur będzie to wartość 5 w instrukcji jako „natychmiastowego danych”, na przykład x86:
mov eax, 5
Zdolność do instrukcji do przechowywania dowolnych stałych jest ograniczona. Małe stałe są obsługiwane przez większość instrukcji CPU. "Duże" stałe zwykle nie są obsługiwane bezpośrednio. W takim przypadku kompilator zapamięta stałą w pamięci i załaduje ją zamiast niej. Na przykład,
.psect rodata
k1 dd 3141592653
.psect code
mov eax k1
rodzina ARM ma potężny projekt dla ładowania większość stałych bezpośrednio: dowolny 8-bitowa wartość stałą można obracać każdą parzystą liczbę razy. Zobacz this strona 2-25.
Jeden nie-jak-to oczywiste, ale zupełnie inna rzecz jest w sprawozdaniu:
printf("%d", b+c);
Ciąg %d
jest przez nowoczesne semantyki C, stałej tablicy trzech char
. Większość współczesnych implementacji będzie przechowywać je w pamięci tylko do odczytu, więc próby jej zmiany spowodują SEGFAULT, który jest niskim poziomem błędu procesora, który zazwyczaj powoduje natychmiastowe przerwanie programu.
.psect rodata
s1 db '%', 'd', 0
.psect code
mov eax s1
push eax
Ponieważ program nie daje żadnych widocznych efektów, kompilator może całkowicie nie przechowywać niczego. ([Przykład] (https://godbolt.org/g/5DAwmj)) –
Pomijając specyfikę twojego pytania, dane const są ogólnie przechowywane we własnej sekcji, np. ".rodata" (ro tylko do odczytu). W przypadku typów POD, takich jak 'int', wartości pamięci są bezpośrednio zapisywane w tej sekcji pliku wykonywalnego, którą system operacyjny ładuje w pamięci podczas uruchamiania. W takim przypadku nie ma instrukcji, aby zainicjować pamięć - zaczyna się od właściwej wartości w ten sposób! Globalne (niestałe) dane zazwyczaj pojawiają się również w swojej sekcji, np. ".data" lub ".bss" (.bss jest domyślnie inicjalizowane do zera podczas uruchamiania programu, ponownie przez system operacyjny). – Cameron
Szczegóły zależą w dużym stopniu od twojej platformy. Niektóre ISA pozwalają na bezpośrednie wartości w instrukcjach, więc wartości mogą być częścią niektórych instrukcji; inne wartości mogą po prostu być częścią obrazu programu i są określane przez adres. Inne wartości (np. Zero) mogą w ogóle nie wymagać przechowywania, a zamiast tego są dostarczane przez specjalną mechanikę ładowania. –