2016-04-22 33 views
5

Zum Beispiel:Wo werden const Daten gespeichert?

In der Datei demo.c,

#inlcude<stdio.h> 
int a = 5; 
int main(){ 
    int b=5; 
    int c=a; 
    printf("%d", b+c); 
    return 0; 
} 

Für int a = 5, nicht übersetzen die Compiler dies in so etwas wie Speichern 0x5 an der virtuellen Speicheradresse, zum Beispiel Ox0000000f im konst Bereich, so dass für int c = a ist es übersetzt in so etwas wie movl 0x0000000f %eax?

Dann wird für int b = 5 die Nummer 5 nicht in den Const-Bereich gelegt, sondern direkt in eine Assembleranweisung wie mov $0x5 %ebx übersetzt.

+5

Da Ihr Programm keine beobachtbaren Effekte hat, ist es dem Compiler völlig frei, nichts zu speichern. ([Beispiel] (https://godbolt.org/g/5DAwmj)) –

+1

Abgesehen von den Besonderheiten Ihrer Frage werden const-Daten im Allgemeinen in einem eigenen Abschnitt gespeichert, z. ".rodata" (ro für Nur Lesen). Bei POD-Typen wie "int" werden die Speicherwerte direkt in den Abschnitt der ausführbaren Datei geschrieben, den das Betriebssystem beim Starten in den Speicher lädt. In diesem Fall ist keine Instruktion erforderlich, um den Speicher zu initialisieren - er beginnt auf diese Weise mit dem richtigen Wert! Globale (nicht-konstante) Daten erscheinen typischerweise auch in einer eigenen Sektion, z. '.data' oder '.bss' (.bss wird beim Programmstart implizit auf Null gesetzt, wiederum vom Betriebssystem). – Cameron

+2

Die Details hängen sehr von Ihrer Plattform ab. Einige ISAs erlauben unmittelbare Werte in Anweisungen, sodass Werte Teil einer Anweisung sein können. andere Werte können einfach Teil des Programmbildes sein und werden durch Adresse bezeichnet. Andere Werte (wie Null) erfordern möglicherweise überhaupt keinen Speicher und werden stattdessen durch spezielle Lademechanismen bereitgestellt. –

Antwort

1

Kommt drauf an. Ihr Programm hat mehrere Konstanten:

int a = 5; 

Dies ist eine „statische“ Initialisierung (die auftritt, wenn der Programmtext und die Daten werden vor dem Ausführen geladen). Der Wert wird in dem von a reservierten Speicher gespeichert, der sich in einem Lese-Schreib-Daten- "Programmabschnitt" befindet. Wenn sich etwas ändert a, ist der Wert 5 verloren.

int b=5; 

Dies ist eine lokale Variable mit begrenztem Umfang (nur durch main()). Der Speicher könnte ein CPU-Register oder ein Ort auf dem Stapel sein. Die erzeugten Instruktionen für die meisten Architekturen wird der Wert 5 in einer Anweisung als „unmittelbare Daten“, für ein x86-Beispiel setzen:

mov eax, 5 

Die Fähigkeit, Anweisungen willkürliche Konstanten zu halten, begrenzt ist. Kleine Konstanten werden von den meisten CPU-Anweisungen unterstützt. "Große" Konstanten werden normalerweise nicht direkt unterstützt. In diesem Fall würde der Compiler die Konstante im Speicher speichern und stattdessen laden. Zum Beispiel

 .psect rodata 
k1  dd  3141592653 
     .psect code 
     mov  eax k1 

Die ARM-Familie verfügt über eine leistungsfähige Design für die meisten Konstanten direkt geladen: all 8-Bit konstanter Wert jede gerade Anzahl von Malen gedreht werden kann. Siehe this Seite 2-25.

Ein nicht-so-offensichtlich, aber ganz anderer Artikel ist in der Aussage:

printf("%d", b+c); 

Der String %d ist, durch moderne C-Semantik, eine konstante Anordnung von drei char. Die meisten modernen Implementierungen werden es in einem Nur-Lese-Speicher speichern, so dass Versuche, es zu ändern, ein SEGFAULT verursachen, was ein niedriger CPU-Fehler ist, der normalerweise bewirkt, dass das Programm sofort abbricht.

 .psect rodata 
s1  db  '%', 'd', 0 
     .psect code 
     mov  eax s1 
     push eax 
+0

das ist in einem Lese-Schreib-Daten "Programmabschnitt", so ist es im .data-Abschnitt? –

+0

@Gab: Ich verwendete die Semantik eines Intel-Assemblers aus den 1980ern. Es gab nichts namens '.data'. Stattdessen gab es psects mit den Namen 'rodata',' rwdata' und 'stack'. Diese würden in ein "Segment" namens "Daten" gruppiert werden. – wallyk

+0

In meinem Beispiel, für 'int b = 5;', können wir sagen, dass die "Daten" 5 direkt in der Anweisung als direkte Zahl gespeichert ist, oder? Also erscheint diese "5" im Code-Segment? –

1

Im OP des Programms a ist ein "initialisiert" "global". Ich erwarte, dass es im initialisierten Teil des Datensegments platziert wird. Siehe https://en.wikipedia.org/wiki/File:Program_memory_layout.pdf, http://www.cs.uleth.ca/~holzmann/C/system/memorylayout.gif (von more info on Memory layout of an executable program (process)). Die Position a wird vom Compiler-Linker-Duo festgelegt.

Andererseits werden im Stack-Segment automatisch (Stack-) Variablen b und c erwartet.

Der Compiler/Linker hat die Freiheit, jede Optimierung durchzuführen, solange das beobachtete Verhalten nicht verletzt wird (What exactly is the "as-if" rule?). Zum Beispiel, wenn a nie referenziert wird, dann kann es vollständig optimiert werden.

Verwandte Themen