Wie wird der Speicher für nicht deklarierte Entitäten in der Sprache C verwaltet?

8

Zum Beispiel: Wie und wo wird im folgenden Code die für den Vergleich verwendete Zahl "10" gespeichert?

%Vor%

Entschuldigen Sie, dass ich nicht genug Details gebe. Anstatt "x" direkt mit "5" zu initialisieren, wissen wir, wie wir den Speicher für "x" reservieren. Aber wie wird Speicher für die Literalzahl '10' zugewiesen, die nicht in einer Variablen gespeichert ist?

    
Vivek A 04.09.2015, 09:34
quelle

2 Antworten

32

In Ihrem speziellen Code ist x auf 5 initialisiert und wird nie geändert. Ein Optimierungscompiler kann konstante Falte und propagieren diese Informationen. Es würde also wahrscheinlich das Äquivalent von

erzeugen %Vor%

Beachten Sie, dass der Compiler auch die Beseitigung von toten Codes vorgenommen hätte.

Also wären die Konstanten 5 und 10 verschwunden.

BTW, <conio.h> und getch sind nicht im Standard C99 oder C11. Mein Linux-System hat sie nicht.

Im Allgemeinen (und abhängig vom Befehlssatz des Zielprozessors und dem ABI ) kleine Konstanten sind oft in einigen einzelnen Maschinencode eingebettet Anweisung (als unmittelbarer Operand), als antwortete Kilian . Einige große Konstanten (z. B. Fließkommazahlen, Literalstrings, die meisten const global oder static Arrays und Aggregate) können als schreibgeschützte Daten in Code-Segment (dann wäre die Konstante innerhalb von Maschinenregister-Ladeanweisungen eine Adresse oder ein Offset relativ zu PC für PIC ); siehe auch dies . Einige Architekturen (zB SPARC , RISC-V , ARM und andere RISC ) können eine breite Konstante in einem Register durch zwei aufeinanderfolgende Anweisungen (Laden der Konstanten in zwei Teile) laden, was sich auf die relocation Format für den Linker (zB in Objektdateien und ausführbare Dateien , oft in ELF ).

Ich schlage vor, dass Sie Ihren Compiler bitten, Assemblercode auszugeben, und werfen Sie einen Blick auf diesen Assemblercode. Wenn Sie GCC verwenden (zB unter Linux oder mit Cygwin oder MinGW ) versuchen mit gcc -Wall -O -fverbose-asm -S zu kompilieren; auf meinem Debian / Linux System, wenn ich getch durch getchar in deinem Code ersetze bekomme ich:

%Vor%

Wenn Sie ein 64-Bit-Windows-System verwenden, ist Ihre Architektur sehr wahrscheinlich x86-64 . Es gibt Tonnen von Dokumentation , die den ISA beschreiben (siehe Antworten auf dies ) und die x86 Aufrufkonventionen (und auch die Linux x86-64 ABI ; Sie finden die gleiches Dokument für Windows).

Übrigens, Sie sollten sich nicht wirklich darum kümmern, wie solche Konstanten implementiert werden. Die Semantik Ihres Codes sollte sich nicht ändern, unabhängig davon, welcher Compiler sie implementiert. Also lassen Sie die Optimierungen (und solche Low-Level-Optionen) für den Compiler (d. H. Ihre Implementierung von C).

    
Basile Starynkevitch 04.09.2015 10:15
quelle
12

Die Konstante 10 wird wahrscheinlich als eine unmittelbare Konstante im Opcode-Strom gespeichert. Die Ausgabe eines CMP AX,10 mit der im Opcode enthaltenen Konstante ist normalerweise kleiner und schneller als ein CMP AX, [BX] , wobei der Vergleichswert aus dem Speicher geladen werden muss.

Wenn die Konstante zu groß ist, um in den Opcode zu passen, besteht die Alternative darin, sie wie eine statische Variable im Speicher abzulegen, aber wenn der Befehlssatz eingebettete Konstanten zulässt, sollte ein guter Compiler ihn verwenden - schließlich diesen Adressierungsmodus wurde vermutlich hinzugefügt, weil es Vorteile gegenüber den anderen hat.

    
Kilian Foth 04.09.2015 09:48
quelle

Tags und Links