2009-08-11 18 views
8

Ich habe ein kleines Problem beim Lernen. Ich weiß, dass nicht initialisierte globale Variablen in C dem Abschnitt .bss in der ausführbaren ELF-Datei zugewiesen sind. Aber was passiert mit ihnen, wenn ich sie benutze? I.e. bekommen sie einen Platz auf dem Haufen oder woanders?Wohin gehen nicht initialisierte globale Variablen nach der Initialisierung?

Ich habe versucht, durch Druck die Adresse der (noch nicht initialisiert) globalen Variable, um herauszufinden, mit

printf("%x",&glbl); 

, die immer den gleichen Wert 0x80495bc zurückkehren ... Warum?

+1

Ich habe bemerkt, dass Sie eine Antwort 5 Minuten nach dem Stellen der Frage angenommen haben. Sie erhalten mehr Antworten, wenn Sie es für einige Zeit offen lassen, da die Leute mehr motiviert sind, die Antworten zu verbessern. – Adriaan

+0

Danke für den Hinweis, ich werde es beim nächsten Mal sicher tun. – Patrick

Antwort

8

Wenn das Betriebssystem Ihr Programm lädt, weist es genügend Speicherplatz aus dem Adressbereich Ihres Programms zu, um alles im Abschnitt .bss zu speichern, und löscht den gesamten Speicher. Wenn Sie die Adresse der Variablen zuweisen oder davon lesen, bearbeiten Sie den Speicher, der für die Bereitstellung des Speichers für den Abschnitt .bss reserviert wurde.

+0

Ah und dies erklärt auch, warum der Wert der nicht initialisierten globalen Variablen immer Null war. Vielen Dank! – Patrick

+0

Einige Compiler/Architekturen unterstützen einen SBSS-Abschnitt für kleine Daten. Dies wird oft als eine Optimierung durchgeführt, so dass die Daten durch Indizierung vom Beginn des SBSS-Abschnitts abgerufen werden können. Dies kann oft mithilfe des gp-Registers und der 16-Bit-Indizierung erfolgen – zebrabox

2

Die globalen Variablen erhalten immer statischen Speicher. Wenn sie nicht initialisiert sind, haben sie keinen Platz in der Binärdatei, aber sie erhalten sie im Speicher, wenn die Binärdatei in den Prozessspeicherbereich geladen wird.

1

Der BSS ist ein Platzhalter, der in Ihrem ausführbaren (oder ELF-) Format definiert ist. Es nimmt also keinen Speicherplatz ein, sondern gibt nur an, welche Speicherregion vom Linker oder Loader zugewiesen werden soll.

Die genaue Funktionsweise hängt vom Betriebssystem ab. Da Sie sich auf ELF beziehen, gehe ich davon aus, dass es für den Einsatz in einem Embedded-System gedacht ist. Wenn Sie für ROM-fähigen Code erstellen, wird Ihre Linker-Cmd-Datei die BSS einer statischen Adressregion zuordnen.

Wenn Sie für ein Betriebssystem (d. H. Linux) erstellen, führt der Loader des Betriebssystems einen Relocation-Pass aus, in dem alle als relativ im executable-Format markierten Speicherorte physischen oder logischen Speicherorten zugeordnet werden.

Da Sie erwähnen, dass immer der gleiche Wert angezeigt wird, zeigt dies an, dass der Prozess für Ihr System wiederholbar ist. Erwarten Sie Änderungen zu sehen, wenn Sie Linker-Dateien ändern (d. H. Adressregionen), Verbindungsreihenfolge (d. H. Module erhalten zugewiesenen Platz in einer anderen Reihenfolge) oder Betriebssystem.

Unabhängig davon, ob Sie die BSS-Werte verwenden oder nicht, bleibt die Adresse für den ausgeführten Prozess gleich.

1

Dieser BSS-Abschnitt erhält einen Speicherblock im Prozessadressraum genau wie die Code- und Stackabschnitte (und alle anderen ELFs). Einmal dort, gehen sie nicht überall hin. Der Lader ordnet die Dinge an und ruft dann den Prozesspunkt auf.

Verwandte Themen