Forum: Compiler & IDEs Position von Code + Variablen in Binary


von meckerziege (Gast)


Lesenswert?

Hi,

ich hab die letzten Tage ein wenig herumexperimentiert und dabei 
folgende Beobachtung gemacht: Wenn ich Variablen umbenenne (nicht 
verschiebe!), dann hat das manchmal(!) Einfluss auf ihre 
Speicheradresse.
Das stört mich nicht weiter, aber ich hab mich gefragt, wie der Linker 
die Variablen überhaupt anordnet.

Es scheint ja nicht alphabetisch zu sein, aber wohl auch nicht in der 
Reihenfolge des Auftretens. Vermutlich ist das völlig unspezifiziert und 
er darfs machen wie er will?


Ist das bei Code auch so? Ich habe beobachtet, dass der Code, der 
"weiter vorne" beim Linkeraufruf kommt, auch zuerst im Binary steht. 
Muss das so sein oder ist auch das unspezifiziert? Ich kenn ein paar 
Programme die verlassen sich auf sowas.


Also: Wie und warum macht der Linker das so, und MUSS er das auch machen 
oder darf sich das in der nächsten Version ändern?

(nur mal so aus Interesse, ich weiß wie man anständig Code+Daten sicher 
an eine fest Adresse bekommt!)

Danke!

von Werner M. (Gast)


Lesenswert?

meckerziege schrieb:
> der Linker

Was ist "der Linker"? Warum sollten verschiedene Linker die Variablen 
nicht verschieden ablegen? Und wenn du das mit dem Quellcode 
vergleichst, haben Compiler und Optimierer auch noch ein Wörtchen mit zu 
reden. Registervariablen tauchen z.B. gar nicht im Speicher auf und was 
zu Registervariablen wird, hängt von der Optimierung ab.

Und der Name sagt nun ausgesprochen wenig. Wie sagte man mein EMP-Prof. 
immer: "Namen sind Schall und Rauch".

> Ich habe beobachtet, dass der Code, der
> "weiter vorne" beim Linkeraufruf kommt, auch zuerst im Binary steht.
> Muss das so sein oder ist auch das unspezifiziert?

Das wird wohl auf den von dir verwendeten Linker ankommen. Irgendeine 
Reihenfolge muss der Linker verwenden und wenn ihm nichts Besseres 
"einfällt", i.e. es keine besonderen Gründe gibt, ist es doch 
naheliegend, alles der Reihe nach abzulegen - so wie es kommt.

von meckerziege (Gast)


Lesenswert?

Werner M. schrieb:
> Was ist "der Linker"?

Nachdem das Forum hier "GCC" heißt, wirds wohl auch der GCC Linker sein. 
Also "ld" um ihn mal zu rufen...

> Warum sollten verschiedene Linker die Variablen
> nicht verschieden ablegen?

exakt das war meine Frage. Gibt es dort harte Vorgaben oder nicht?


Werner M. schrieb:
> [..] wenn ihm nichts Besseres
> "einfällt", i.e. es keine besonderen Gründe gibt, ist es doch
> naheliegend, alles der Reihe nach abzulegen - so wie es kommt.

gibt es denn "besondere Gründe"? (Linkerscript mal ausgenommen)

von Werner M. (Gast)


Lesenswert?

meckerziege schrieb:
> gibt es denn "besondere Gründe"?

Einer wäre die schon genannte Optimierungsstufe. Oder das Packen der 
Variablen.

von Rolf M. (rmagnus)


Lesenswert?

meckerziege schrieb:
> Werner M. schrieb:
>> Was ist "der Linker"?
>
> Nachdem das Forum hier "GCC" heißt, wirds wohl auch der GCC Linker sein.
> Also "ld" um ihn mal zu rufen...
>
>> Warum sollten verschiedene Linker die Variablen
>> nicht verschieden ablegen?
>
> exakt das war meine Frage. Gibt es dort harte Vorgaben oder nicht?

Nun, die Elemente eines Arrays müssen natürlich alle hintereinander 
liegen, und die Elemente einer Struktur müssen in der Reihenfolge 
gespeichert sein, in der sie definiert sind, aber bei von einander 
unabhängigen Variablen gibt es keinerlei Vorgaben zum Speicherort.

meckerziege schrieb:
> Werner M. schrieb:
>> [..] wenn ihm nichts Besseres
>> "einfällt", i.e. es keine besonderen Gründe gibt, ist es doch
>> naheliegend, alles der Reihe nach abzulegen - so wie es kommt.
>
> gibt es denn "besondere Gründe"? (Linkerscript mal ausgenommen)

Globale Variablen, die (implizit oder explizit) mit 0 initialisiert 
werden, kommen in der Regel in einen eigenen Bereich. Je nach 
Zielplattform können als const definierte Variablen z.B. im Flash 
stehen, die anderen im RAM. Außerdem kann der Compiler Variablen auch 
z.B. so umsortieren, daß möglichst wenig "Verschnitt" durch die 
Alignment-Anforderungen entsteht oder so, daß möglichst viele davon in 
einem besonders schnell zugreifbaren Speicher stehen. Da kann es viele 
Gründe geben, die aber größtenteils dann von der Zielplattform abhängen.

von Markus F. (mfro)


Lesenswert?

Rolf Magnus schrieb:
> können als const definierte Variablen z.B. im Flash
> stehen

Es mag eine Entscheidung des Programmierers sein, const definierte 
Variablen ins Flash zu packen, ein Compiler sollte das von sich aus aber 
bleiben lassen.

"const" heißt nicht "Konstante". Es heißt nur "_ich_ schreib' nicht 
drauf" - "readonly" wäre als Qualifier zweifellos besser gewesen.

Wer "const" mit "konstant" gleichsetzt, kommt spätestens bei "const 
volatile" ins Schwimmen ;).

von Rolf M. (rmagnus)


Lesenswert?

Markus F. schrieb:
> Rolf Magnus schrieb:
>> können als const definierte Variablen z.B. im Flash
>> stehen
>
> Es mag eine Entscheidung des Programmierers sein, const definierte
> Variablen ins Flash zu packen, ein Compiler sollte das von sich aus aber
> bleiben lassen.

Ich sehe nichts, was dagegen spricht.

> "const" heißt nicht "Konstante". Es heißt nur "_ich_ schreib' nicht
> drauf" - "readonly" wäre als Qualifier zweifellos besser gewesen.

Ja, eben. Mit const gibst du dem Compiler das Versprechen, daß du den 
Wert nicht ändern wirst. Der Compiler darf dieses Versprechen für seine 
Optimierung nutzen. Wenn du trotzdem versuchst, den Wert zu ändern, ist 
dein Programm fehlerhaft, das Verhalten ist undefiniert. Warum sollte 
der Compiler die Variable also nicht in den Flash-Speicher stecken 
dürfen?

> Wer "const" mit "konstant" gleichsetzt, kommt spätestens bei "const
> volatile" ins Schwimmen ;).

Auch da spricht nichts dagegen, die Variable im Flash zu halten.

Übrigens: Auf meinem Linux-PC wird folgendes Programm mit einem 
Segmentation Fault terminiert:
1
#include <stdio.h>
2
3
const int i = 5;
4
5
int main()
6
{
7
    *(int*)&i = 7;
8
    printf("%d\n", i);
9
    return 0;
10
}
1
Program received signal SIGSEGV, Segmentation fault.
2
0x000000000040053f in main () at const.c:7
3
7           *(int*)&i = 7;

Ohne den Cast bekomme ich es nicht einmal durch den Compiler.
Da sagt er dann:
1
const.c: In function ‘main’:
2
const.c:7:7: error: assignment of read-only variable ‘i’
3
     i = 7;
4
       ^
5
<builtin>: recipe for target 'const' failed

von Markus F. (mfro)


Lesenswert?

Rolf Magnus schrieb:
> Auch da spricht nichts dagegen, die Variable im Flash zu halten.

dann ändere dein Testprogramm mal nach:
1
const volatile int i = 5;

Du wirst feststellen, daß es dann durchläuft.

Also lieber nicht in's Flash mit der Variable, es könnte ja jemand 
anderes drauf schreiben ;).

von Rolf M. (rmagnus)


Lesenswert?

Markus F. schrieb:
> Also lieber nicht in's Flash mit der Variable, es könnte ja jemand
> anderes drauf schreiben ;).

... wenn sie eben volatile ist. Das hat dann aber mit dem const erstmal 
nichts zu tun.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.