Hallo Geier,
Zu 1)
Das sind alte Geschichten aus den Anfängen von C.
Das Source-Programm wird dem Compiler als Text-Datei gefüttert.
.code wurde vor C schon für den Code von Assemblerprogrammen verwendet.
Also kam da einer auf die Idee, das Segment halt .text zu benennen, welches den Maschinencode des C-Programms enthält.
Das cstartup-Modul, welches die CPU-Register und noch ein paar Dinge initialisiert, bevor main() aufgerufen wird, ist meist immer noch in Assembler geschrieben und liegt typischerweise im .code-Segment.
.bss wird für statische Variablen verwendet.
.data enthält initialisierte statische variablen.
Dann gibt es oft noch .stack oder .cstack für den Bereich welcher den Stack enthält.
Die ganzen .debug_xxx-Segmente sind Metadaten für den Debugger und werden nicht auf dem Zielsystem abgelegt. Ein Sourcelevel-Debugger kann damit den Maschinen-Code mit dem Source-Code verknüpfen und alles entsprechend darstellen.
Grundsätzlich sind die Segmentnamen frei wählbar, es gibt halt aber Traditionen für deren Namen.
Bei einem µC werden .code, .text und .data im ROM abgelegt.
cstartup kopiert dann das .data-Segment ins RAM, somit haben alle Variablen einen Anfangswert.
.bss ist einfach der Bereich für statische Variablen ohne Initialisierung. Normalerweise füllt cstartup diesen Bereich des RAM mit Nullen.
http://www.atmel.com/webdoc/avrlibcr..._sections.html
Die Segmente braucht der Linker um die einzeln übersetzten Module zusammensetzen zu können. Im einfachsten Fall ist dies dein Programm und die Bibliotheks-Funktionen, bei grösseren Projekten wird auch das Anwendungsprogramm in mehrere Module aufgeteilt. Im Object-Code dieser Module gibt es noch keine absoluten Adressen, weil noch nicht bekannt ist, wo sie im Speicher zu liegen kommen.
Der Linker büschelt dann erst mal alles schön zusammen, also alle .text-Segmente werden in einem Block hintereinander gehängt, ebenso .data, .bss und all die anderen in jeweils ihrem Block. Anschliessend kann dann der Linker die absoluten Adressen generieren und an den richtigen Stellen im Code eintragen.
Module, welche besonders viel Stack benötigen, können dann auch noch ein entsprechend grosses Stack-Segment reservieren.
Zum Linker gehört auch noch eine Steuer-Datei. In dieser kann man ablegen auf welchen Adressen ROM und RAM im Speicherbereich abgelegt sind und welche Segmente wo abgelegt werden sollen.
Wenn man dies beherrscht kann man recht tolle Sachen machen! z.B. kann man die Datensegmente von der niedrigsten RAM-Adresse aus ablegen und das Stack-Segment von der höchsten RAM-Adresse aus. Da normalerweise der Stack von oben nach unten wächst hat man die grösste Sicherheit gegen einen Stackoverflow. Alles nicht belegte RAM befindet sich dann zwischen Daten und Stack. Bei besseren Linkern müssen der RAM- und ROM-Bereich auch nicht zusammenhängend sein, bei richtiger Konfiguration der Steuerdatei macht das dann der Linker automatisch.
Zu 2)
http://www.atmel.com/images/Atmel-82...t_Complete.pdf
ATmega 48A/48PA und ATmega88A/88PA haben 2 Byte für den Vektor.
ATmega168A/168PA und ATmega328/328P haben 4 Byte.
Abschnitt 2.2, Seite 7.
Zu 3)
Das ist eine harte Frage!
Es gibt kaum grundlegende Werke zu Linkern. Da ist man halt Profi und kommt mit den technischen Angaben zurecht. War irgendwie schon immer so
Hier mal eine Einführung in den Linker:
http://www.seceng.informatik.tu-darm...binder0910.pdf
Etwas älter (1972) aber ausführlicher:
http://www-inst.eecs.berkeley.edu/~c...ker-loader.pdf
Allerdings weiss ich noch nicht, welche Info dir zum Linker wirklich fehlen?
Scheint aber noch einiges an Grundlagen zu fehlen.
MfG Peter(TOO)
Lesezeichen