(→Compiler-Vergleiche) |
K (→Siehe auch) |
||
(24 dazwischenliegende Versionen von 4 Benutzern werden nicht angezeigt) | |||
Zeile 4: | Zeile 4: | ||
seltsamer Form doch nur ein 1:1 Bild der Bits und Bytes ist, wie sie dann im Speicher stehen. Und das sind feststehende Daten (wie z.B. Umrechnungs-Tabellen), und | seltsamer Form doch nur ein 1:1 Bild der Bits und Bytes ist, wie sie dann im Speicher stehen. Und das sind feststehende Daten (wie z.B. Umrechnungs-Tabellen), und | ||
das übersetzte Programm. | das übersetzte Programm. | ||
− | + | ||
− | [[Bild: | + | {| |
+ | |[[Bild:Compiler1.png]] | ||
+ | |- | ||
+ | |<div align="center">Schematischer Ablauf der Compilerung anhand der Beispiele BASCOM, FASTAVR und GCC</div> | ||
+ | |} | ||
+ | |||
+ | Die Code-Erzeugung geschieht meistens in mehreren Schritten, die oft auch explizit in einem sogenannten [[make|"makefile"]] stehen können. | ||
+ | ; Precompilerung: Es werden die Anweisung aufgelöst, mit denen der Sourcecode eigentlich erst vollständig wird, wie Makros und symbolische Namen. Meistens sind solche Anweisungen an bestimmten vorangestellten Zeichen erkennbar, wie z.B. "#" (C/C++) und "$" (BasCom). | ||
+ | ; Compilierung: Der eigentliche Compile-Vorgang, bei dem oft erstmal nur "Objects" erzeugt werden (Das ist zwar schon Maschinencode, aber noch mit vorläufigen Sprung- und Datenadressen). | ||
+ | ; Linken: bindet diese Objekte zusammen und ersetzt die verschieblichen Adressen durch absolute Werte | ||
+ | |||
+ | Und eventuell noch | ||
+ | ; Konvertieren: um die endgültige "HEX" File zu erhalten | ||
===Varianten der Programmentwicklung=== | ===Varianten der Programmentwicklung=== | ||
===="Echte" Compiler==== | ===="Echte" Compiler==== | ||
Das sind zum Beispiel Assembler, Bascom, GCC. Die verhalten sich genau so wie in der Darstellung und erzeugen mehr oder weniger direkt den Maschinen-code für einen ganz | Das sind zum Beispiel Assembler, Bascom, GCC. Die verhalten sich genau so wie in der Darstellung und erzeugen mehr oder weniger direkt den Maschinen-code für einen ganz | ||
− | konkreten Controller. "FastAVR", den ich aber mangels besserer Kenntnis hier nur erwähnen will, ist wohl eher ein Programm-Generator. | + | konkreten Controller. "FastAVR", den ich aber mangels besserer Kenntnis hier nur erwähnen will, ist wohl eher ein Programm-Generator. |
====Program-Generator==== | ====Program-Generator==== | ||
Zeile 24: | Zeile 36: | ||
===="Basic" Controller==== | ===="Basic" Controller==== | ||
(PICAXE) Auch hier wird in zwei Teilen kompiliert /übersetzt: Erstmal ein Basic-Dialekt in eine Art "Token"-Format (kann man als "Kürzel" bezeichnen). Dieses Format wird dann | (PICAXE) Auch hier wird in zwei Teilen kompiliert /übersetzt: Erstmal ein Basic-Dialekt in eine Art "Token"-Format (kann man als "Kürzel" bezeichnen). Dieses Format wird dann | ||
− | auf den Controller geladen und hier läuft dann als "Firmware" ein Interpreter, der diese Token dann für den RISC-Controller aufbereitet. | + | auf den Controller geladen und hier läuft dann als "Firmware" ein Interpreter, der diese Token dann für den RISC-Controller aufbereitet. |
− | + | ||
===Source Code=== | ===Source Code=== | ||
Recht grob, aber doch, besteht jedes Programm für jeden Compiler (mit unterschiedlicher Gewichtung) aus drei Teilen: | Recht grob, aber doch, besteht jedes Programm für jeden Compiler (mit unterschiedlicher Gewichtung) aus drei Teilen: | ||
====Definition des Zielsystems==== | ====Definition des Zielsystems==== | ||
− | Man muß dem Compiler sagen, für welchen Controller er den Code generieren soll. Meistens durch " | + | Man muß dem Compiler sagen, für welchen Controller er den Code generieren soll. Meistens durch "Kommandozeilen-Parameter" (GCC) oder "$Regfile= xxx " (Bascom). Die Absicht ist, daß man |
den restlichen Source-Code nicht ändern muß, wenn man einen anderen Controller verwenden will. Das ist aber schon recht theoretisch, denn so standardisiert, wie es | den restlichen Source-Code nicht ändern muß, wenn man einen anderen Controller verwenden will. Das ist aber schon recht theoretisch, denn so standardisiert, wie es | ||
− | bei den PCs ist (durch das Betriebssystem), sind die Microcontroller beileibe nicht. | + | bei den PCs ist (durch das Betriebssystem), sind die Microcontroller beileibe nicht. |
+ | |||
+ | ====Deklaration der Daten==== | ||
+ | Bekanntmachung, welche Daten/Funktionen verwendet werden, um andere Module darüber in Kenntnis zu setzen. Eine Deklaration ist zu unterscheiden von einer Definition. | ||
+ | |||
====Definition der Daten==== | ====Definition der Daten==== | ||
Hier wird definiert, mit welchen Daten das Programm arbeiten soll. Beim '''Assembler''' kann man das auch bleibenlassen, der ist da nicht so heikel, im anderen Extrem, bei den ++ Objekt-orientierten Sprachen, muß hier bereits recht detailliert beschrieben werden, was man braucht und wie man mit diesen Daten im restlichen Programm denn | Hier wird definiert, mit welchen Daten das Programm arbeiten soll. Beim '''Assembler''' kann man das auch bleibenlassen, der ist da nicht so heikel, im anderen Extrem, bei den ++ Objekt-orientierten Sprachen, muß hier bereits recht detailliert beschrieben werden, was man braucht und wie man mit diesen Daten im restlichen Programm denn | ||
umgehen will. | umgehen will. | ||
+ | *'''Elementare Datentypen''': Typen, die zum Sprachumfang gehören | ||
*'''Einzelfelder''': eines oder mehrere Byte, die zusammen eine bestimmten Datentyp bilden | *'''Einzelfelder''': eines oder mehrere Byte, die zusammen eine bestimmten Datentyp bilden | ||
*'''Arrays''': das sind ein- oder mehrdimensionale Tabellen, wobei die Elemente Einzelfelder, aber auch Strukturen sein können | *'''Arrays''': das sind ein- oder mehrdimensionale Tabellen, wobei die Elemente Einzelfelder, aber auch Strukturen sein können | ||
*'''Strukturen''': Zusammenfassung von Einzelfeldern oder anderen Strukturen zu zusammenhängenden Einheiten | *'''Strukturen''': Zusammenfassung von Einzelfeldern oder anderen Strukturen zu zusammenhängenden Einheiten | ||
+ | |||
+ | ====Adressierung der Daten==== | ||
+ | *direkt | ||
+ | Das Datum wird direkt mit seiner Adresse angesprochen, meist symbolisch durch einen eindeutigen Namen. | ||
+ | *indirekt | ||
+ | Die Datenadresse steht in einem Pointer (Zeiger), und dieser Pointer wird im Programm angegeben. (Das geht bei vielen Sprachen auch mehrstufig, d.h. die adresse der adresse). | ||
====Befehle==== | ====Befehle==== | ||
Das eigentliche Programm in Form von mehr oder weniger symbolischen und/oder abstrakten Anweisungen. Auch hier gibt es Unterscheidungen | Das eigentliche Programm in Form von mehr oder weniger symbolischen und/oder abstrakten Anweisungen. Auch hier gibt es Unterscheidungen | ||
− | + | =====Anweisungen===== | |
+ | *Zuweisungen | ||
Variable = ausdruck | Variable = ausdruck | ||
− | *Verzweigung | + | *Funktionsdefinitionen |
− | GOTO | + | Variable = funktion (argument) |
− | + | ||
+ | Dabei ist "argument" eine Liste von Ausdrücken (die aber auch leer sein kann) | ||
+ | =====Anweisungsblöcke===== | ||
+ | Mehrere Anweisungen werden als "Block" zusammengefaßt, das ist vor allem für die folgenden Ablauf-Kontrollbefehle relevant. | ||
+ | |||
+ | =====Kontrollstrukturen===== | ||
+ | *Unbedingte Verzweigung | ||
+ | GOTO | ||
+ | |||
CALL /GOSUB ... RETURN | CALL /GOSUB ... RETURN | ||
− | * | + | Da die aufgerufene Prozedur mit RETURN wieder zurückkehrt, muß man den Begriff "Verzweigung" allerdings etwas relativiert sehen |
+ | *Bedingte Verzweigung | ||
IF (Bedingung) THEN ... ELSE .... END IF | IF (Bedingung) THEN ... ELSE .... END IF | ||
− | *Auswahl | + | *Auswahl / Bedingte Mehrfach-Verzweigung |
SELECT CASE ..... END SELECT | SELECT CASE ..... END SELECT | ||
*Wiederholungs-Schleifen | *Wiederholungs-Schleifen | ||
Wichtige Unterscheidung ist, ob die Schleifenbedingung VOR oder NACH den enthaltenen Anweisungen geprüft wird | Wichtige Unterscheidung ist, ob die Schleifenbedingung VOR oder NACH den enthaltenen Anweisungen geprüft wird | ||
− | DO .. WHILE | + | DO .. WHILE Prüfung am Ende des Durchlaufs |
− | + | ||
− | WHILE ... WEND | + | WHILE ... WEND Prüfung vorher |
− | FOR .. NEXT | + | FOR .. NEXT (Sonderform von WHILE...WEND, meist als Zählschleife) |
+ | ==Siehe auch== | ||
+ | * [[Bascom]] | ||
+ | * [[avr-gcc/Interna]] | ||
+ | * [[WinAVR]] | ||
[[Kategorie:Grundlagen]] | [[Kategorie:Grundlagen]] | ||
[[Kategorie:Software]] | [[Kategorie:Software]] |
Aktuelle Version vom 21. Februar 2007, 17:16 Uhr
Inhaltsverzeichnis
Compiler
Das, was letzlich ein Micro-Controller tut, wird ausschließlich durch das bestimmt, was wir in den Program-Flash reinladen. Üblicherweise ist das eine "*.HEX" Datei, die in etwas seltsamer Form doch nur ein 1:1 Bild der Bits und Bytes ist, wie sie dann im Speicher stehen. Und das sind feststehende Daten (wie z.B. Umrechnungs-Tabellen), und das übersetzte Programm.
Schematischer Ablauf der Compilerung anhand der Beispiele BASCOM, FASTAVR und GCC
|
Die Code-Erzeugung geschieht meistens in mehreren Schritten, die oft auch explizit in einem sogenannten "makefile" stehen können.
- Precompilerung
- Es werden die Anweisung aufgelöst, mit denen der Sourcecode eigentlich erst vollständig wird, wie Makros und symbolische Namen. Meistens sind solche Anweisungen an bestimmten vorangestellten Zeichen erkennbar, wie z.B. "#" (C/C++) und "$" (BasCom).
- Compilierung
- Der eigentliche Compile-Vorgang, bei dem oft erstmal nur "Objects" erzeugt werden (Das ist zwar schon Maschinencode, aber noch mit vorläufigen Sprung- und Datenadressen).
- Linken
- bindet diese Objekte zusammen und ersetzt die verschieblichen Adressen durch absolute Werte
Und eventuell noch
- Konvertieren
- um die endgültige "HEX" File zu erhalten
Varianten der Programmentwicklung
"Echte" Compiler
Das sind zum Beispiel Assembler, Bascom, GCC. Die verhalten sich genau so wie in der Darstellung und erzeugen mehr oder weniger direkt den Maschinen-code für einen ganz konkreten Controller. "FastAVR", den ich aber mangels besserer Kenntnis hier nur erwähnen will, ist wohl eher ein Programm-Generator.
Program-Generator
Es gibt auch die Gruppe der "Programm-Generatoren". Die erstellen als Ergebnis einen Source-Code eine anderen Sprache, den man dann nochmals übersetzen muß. Bei einigen Micro-Controller-Compilern ist es auch so, daß die als Zwischen- oder Nebenprodukt Assemblercode herstellen, den man noch überarbeiten könnte, wenn man das will. Die Tücke dabei ist, daß das aber nicht umgekehrt geht, d.h. bei jeder Änderung der ursprünglichen Source muß man solche Anpassungen nochmal machen.
Virtual Machines
Compiler dieser Kategorie (JAVA) erzeugen ebenfalls Maschinencode, aber für eine Maschine, die es eigentlich garnicht gibt. Auf dem Zielsystem (Prozessor, Controller) läuft dann ein Programm, daß diesen Code zum Laufzeitpunkt auf den realen Maschinencode umsetzt. Der Gedanke ist ja nicht schlecht: Ich kann für alle möglichen Rechner EINE Applikation entwickeln, daß dann ohne weiteres auf jedem x-beliebigen Computer ablaufen kann, für den es dieses "Umsetz"-Programm gibt.
"Basic" Controller
(PICAXE) Auch hier wird in zwei Teilen kompiliert /übersetzt: Erstmal ein Basic-Dialekt in eine Art "Token"-Format (kann man als "Kürzel" bezeichnen). Dieses Format wird dann auf den Controller geladen und hier läuft dann als "Firmware" ein Interpreter, der diese Token dann für den RISC-Controller aufbereitet.
Source Code
Recht grob, aber doch, besteht jedes Programm für jeden Compiler (mit unterschiedlicher Gewichtung) aus drei Teilen:
Definition des Zielsystems
Man muß dem Compiler sagen, für welchen Controller er den Code generieren soll. Meistens durch "Kommandozeilen-Parameter" (GCC) oder "$Regfile= xxx " (Bascom). Die Absicht ist, daß man den restlichen Source-Code nicht ändern muß, wenn man einen anderen Controller verwenden will. Das ist aber schon recht theoretisch, denn so standardisiert, wie es bei den PCs ist (durch das Betriebssystem), sind die Microcontroller beileibe nicht.
Deklaration der Daten
Bekanntmachung, welche Daten/Funktionen verwendet werden, um andere Module darüber in Kenntnis zu setzen. Eine Deklaration ist zu unterscheiden von einer Definition.
Definition der Daten
Hier wird definiert, mit welchen Daten das Programm arbeiten soll. Beim Assembler kann man das auch bleibenlassen, der ist da nicht so heikel, im anderen Extrem, bei den ++ Objekt-orientierten Sprachen, muß hier bereits recht detailliert beschrieben werden, was man braucht und wie man mit diesen Daten im restlichen Programm denn umgehen will.
- Elementare Datentypen: Typen, die zum Sprachumfang gehören
- Einzelfelder: eines oder mehrere Byte, die zusammen eine bestimmten Datentyp bilden
- Arrays: das sind ein- oder mehrdimensionale Tabellen, wobei die Elemente Einzelfelder, aber auch Strukturen sein können
- Strukturen: Zusammenfassung von Einzelfeldern oder anderen Strukturen zu zusammenhängenden Einheiten
Adressierung der Daten
- direkt
Das Datum wird direkt mit seiner Adresse angesprochen, meist symbolisch durch einen eindeutigen Namen.
- indirekt
Die Datenadresse steht in einem Pointer (Zeiger), und dieser Pointer wird im Programm angegeben. (Das geht bei vielen Sprachen auch mehrstufig, d.h. die adresse der adresse).
Befehle
Das eigentliche Programm in Form von mehr oder weniger symbolischen und/oder abstrakten Anweisungen. Auch hier gibt es Unterscheidungen
Anweisungen
- Zuweisungen
Variable = ausdruck
- Funktionsdefinitionen
Variable = funktion (argument)
Dabei ist "argument" eine Liste von Ausdrücken (die aber auch leer sein kann)
Anweisungsblöcke
Mehrere Anweisungen werden als "Block" zusammengefaßt, das ist vor allem für die folgenden Ablauf-Kontrollbefehle relevant.
Kontrollstrukturen
- Unbedingte Verzweigung
GOTO
CALL /GOSUB ... RETURN
Da die aufgerufene Prozedur mit RETURN wieder zurückkehrt, muß man den Begriff "Verzweigung" allerdings etwas relativiert sehen
- Bedingte Verzweigung
IF (Bedingung) THEN ... ELSE .... END IF
- Auswahl / Bedingte Mehrfach-Verzweigung
SELECT CASE ..... END SELECT
- Wiederholungs-Schleifen
Wichtige Unterscheidung ist, ob die Schleifenbedingung VOR oder NACH den enthaltenen Anweisungen geprüft wird
DO .. WHILE Prüfung am Ende des Durchlaufs WHILE ... WEND Prüfung vorher FOR .. NEXT (Sonderform von WHILE...WEND, meist als Zählschleife)