Wenn es nichts zu verknüpfen gibt (d.h. ich verwende keine Bibliotheken. Ich weiß, dass es nicht von Nutzen sein wird.) wird der Linker die Objektcode-Ausgabe von Assembler ändern? Wenn ja, was ändert er?
Er verknüpft immer einen Initialisierungscode. Sie können dies ausprobieren, indem Sie ein leeres Programm schreiben und es linken und dann objdump -d verwenden, um es zu disassemblieren.
Ich habe gehört, dass LINKER auch einige Speicherzuordnungen vornimmt. Ich verstehe nicht, wie. Das Programm läuft nicht, es befindet sich nur in der Herstellungsphase. Wie könnte Linker den Speicher abbilden? Wie würde das aussehen? Was sind die Funktionen von LINKER?
Jedes System hat ein Speicherlayout, dem ausführbare Programme folgen müssen, um zu funktionieren. Es legt fest, wo die verschiedenen Teile des Programms hingehören (zumindest Code, initialisierte Daten, auf Null initialisierte Daten). Der Linker muss die ausführbare Datei nach diesen Regeln erstellen, die von System zu System unterschiedlich sind, z. B. bei Windows und Linux. Bei eingebetteten Systemen wird es sogar noch interessanter, denn dort befindet sich das Programm in der Regel im Nur-Lese-Speicher (Flash) und die Daten im RAM, und je nach Art des Mikrocontrollers gibt es feste Adressbereiche für die verschiedenen Arten von Speicher.
Wenn von "Umzug" die Rede ist, ist damit "Adressbindung" gemeint. verstehe ich nicht wirklich, was sie meinen. Was ist das und was ist der Zweck?
Binden bedeutet im Allgemeinen, einem Namen einen Wert zu geben, in diesem Fall eine Adresse für das Symbol einer Funktion oder einer globalen Variablen.
Was die Verschiebung betrifft, so verknüpfen Sie in der Regel mehrere Objektdateien miteinander, und jede Objektdatei gibt ihre Adressen als Offsets relativ zu ihrem Anfang an. Wenn Sie sie zusammenfügen, erhält jede ihren eigenen Adressbereich, und der Linker berechnet die Adresse für ein Symbol, indem er den Offset auf den Adressbereich abbildet. Dies wird als Relokation bezeichnet.
Einige Debugger zeigen Informationen wie: call stack: 0xfffef32 , 0xf3234fe usw.. Ist das zur Laufzeit richtig oder sind das die Speicheradressen des so genannten "Memory Mapping" des Linkers?
Die Adresse 0xfffef32 wäre eine typische Adresse auf dem Stack, da der Stack in der Regel am Anfang des Speichers liegt und nach unten wächst. Der Stack wird für Rücksprungadressen, lokale Variablen und aktuelle Funktionsparameter verwendet. Diese sind lokal und werden an Adressen relativ zum Stack-Zeiger gespeichert, so dass sie in der Regel nicht vom Linker behandelt werden, sondern der Compiler kennt bereits die zu verwendenden Offsets und fügt sie in den Assembler-Code ein.
wenn von Symbolen oder einer Symboltabelle die Rede ist. Meinen sie Bezeichner (Variablennamen, Konstantennamen, Funktionsnamen)?
Die Symboltabelle ist eine Tabelle, die Symbole auf Werte (Zahlen, Offsets, Adressen) abbildet. Es gibt einige Symbole für Ihre Bezeichner, aber auch mehr für andere Zwecke. Ihre Bezeichner können mehr oder weniger verändert werden, um zu Symbolen zu werden, hauptsächlich um Namenskonflikte zu vermeiden (z. B. das Voranstellen von "_").
Der Linker verfügt über die Option --print-map, um die Symboltabelle zu drucken. Sie können -Wl,--print-map verwenden, wenn Sie gcc zum Linken benutzen.
Wenn Sie diese Art von technischem Low-Level-Kram mögen, sollten Sie einen Blick auf die Embedded-Programmierung werfen, d.h. die Programmierung von Mikrocontrollern, die in verschiedenen elektrischen Geräten eingesetzt werden. Bei Desktop-Systemen wie Windows müssen Sie sich normalerweise nicht mit dieser Art von Details befassen.