K (→Siehe auch) |
|||
Zeile 1: | Zeile 1: | ||
− | Ein wichtiges Merkmal eines | + | Ein wichtiges Merkmal eines [[Compiler]]s ist die Güte des erzeugten Codes. |
− | Immerhin will man seine Hardware optimal nutzen, und die geschriebenen Programme sollen möglichst wenig Laufzeit brauchen und möglichst wenig Speicher – also RAM und Flash – belegen. | + | Immerhin will man seine Hardware optimal nutzen, und die geschriebenen Programme sollen möglichst wenig Laufzeit brauchen und möglichst wenig Speicher – also RAM und [[Flash]] – belegen. |
Ein Vergleich der erzeugten Codes ist jedoch nicht einfach, denn ein Problem kann bereits innerhalb ein und der selben Programmiersprache auf sehr unterschiedliche Art und Weisen formuliert oder gelöst werden. | Ein Vergleich der erzeugten Codes ist jedoch nicht einfach, denn ein Problem kann bereits innerhalb ein und der selben Programmiersprache auf sehr unterschiedliche Art und Weisen formuliert oder gelöst werden. | ||
− | Dieser Artikel versucht ansatzweise einen Codevergleich weit verbreiteter AVR-Compiler anhand sehr einfacher Aufgaben. | + | Dieser Artikel versucht ansatzweise einen Codevergleich weit verbreiteter [[AVR]]-Compiler anhand sehr einfacher Aufgaben, die "geradeaus" und ohne Umschweife programmiert wurden. |
− | Ein Vergleich der Programmierung von Hardware-Komponenten und Peripherie wie UART- oder I2C-Module scheint dabei weniger interessant, denn obwohl die Codes zum Steuern dieser Komponente in unterschiedlichen Sprachen recht verschieden aussehen, werden sie doch auf die selben Maschinen-Codes abgebildet, die sich im wesentlichen auf das Setzen und Lesen von Registern (SFRs) reduzieren. | + | Ein Vergleich der Programmierung von Hardware-Komponenten und Peripherie wie [[Timer]]-, [[UART]]- oder [[I2C]]-Module scheint dabei weniger interessant, denn obwohl die Codes zum Steuern dieser Komponente in unterschiedlichen Sprachen recht verschieden aussehen, werden sie doch auf die selben Maschinen-Codes abgebildet, die sich im wesentlichen auf das Setzen und Lesen von Registern (SFRs) reduzieren. Neben diesen für jedes Programm essenziellen Abschnitten, besteht ein Programm aber zum großen Teil aus hardwareunanhängigen Aufgaben wie Registerverwaltung, Funktionsaufrufen, Schleifen, Abfragen, etc. |
− | Interessanter erscheint ein Vergleich einfacher Aufgaben, die erkennen lassen, wie gut ein Compiler in der Lage ist, die Ressourcen eines | + | Interessanter erscheint ein Vergleich einfacher Aufgaben, die erkennen lassen, wie gut ein Compiler in der Lage ist, die Ressourcen eines [[Mikrocontroller]]s zu nutzen bzw. zu schonen. |
− | = | + | = Summe der ersten ''n'' Zahlen = |
Berechnet wird die Summe der ersten ''n'' Zahlen: | Berechnet wird die Summe der ersten ''n'' Zahlen: | ||
:<math> | :<math> | ||
− | \operatorname{sum}(n) \,=\, \sum_{k= | + | \operatorname{sum}(n) \,=\, \sum_{k=1}^n k |
\,=\, 1 + 2 + \ldots + n | \,=\, 1 + 2 + \ldots + n | ||
</math> | </math> | ||
− | + | Die Zahl ''n'' wird als 16-Bit Zahl angegeben und das Ergebnis als 16-Bit-Zahl berechnet. Ein eventueller Überlauf wird nicht beachtet. | |
Der Code wird jeweils als eigene Funktion implementiert, um Abhängigkeiten vom umliegenden Code zu vermeiden. | Der Code wird jeweils als eigene Funktion implementiert, um Abhängigkeiten vom umliegenden Code zu vermeiden. | ||
+ | |||
+ | Für diese Berechnung gibt es mehrere Möglichkeiten. | ||
== Aufsummieren in einer Schleife == | == Aufsummieren in einer Schleife == |
Version vom 6. April 2006, 17:26 Uhr
Ein wichtiges Merkmal eines Compilers ist die Güte des erzeugten Codes. Immerhin will man seine Hardware optimal nutzen, und die geschriebenen Programme sollen möglichst wenig Laufzeit brauchen und möglichst wenig Speicher – also RAM und Flash – belegen.
Ein Vergleich der erzeugten Codes ist jedoch nicht einfach, denn ein Problem kann bereits innerhalb ein und der selben Programmiersprache auf sehr unterschiedliche Art und Weisen formuliert oder gelöst werden.
Dieser Artikel versucht ansatzweise einen Codevergleich weit verbreiteter AVR-Compiler anhand sehr einfacher Aufgaben, die "geradeaus" und ohne Umschweife programmiert wurden.
Ein Vergleich der Programmierung von Hardware-Komponenten und Peripherie wie Timer-, UART- oder I2C-Module scheint dabei weniger interessant, denn obwohl die Codes zum Steuern dieser Komponente in unterschiedlichen Sprachen recht verschieden aussehen, werden sie doch auf die selben Maschinen-Codes abgebildet, die sich im wesentlichen auf das Setzen und Lesen von Registern (SFRs) reduzieren. Neben diesen für jedes Programm essenziellen Abschnitten, besteht ein Programm aber zum großen Teil aus hardwareunanhängigen Aufgaben wie Registerverwaltung, Funktionsaufrufen, Schleifen, Abfragen, etc.
Interessanter erscheint ein Vergleich einfacher Aufgaben, die erkennen lassen, wie gut ein Compiler in der Lage ist, die Ressourcen eines Mikrocontrollers zu nutzen bzw. zu schonen.
Inhaltsverzeichnis
Summe der ersten n Zahlen
Berechnet wird die Summe der ersten n Zahlen:
- [math] \operatorname{sum}(n) \,=\, \sum_{k=1}^n k \,=\, 1 + 2 + \ldots + n [/math]
Die Zahl n wird als 16-Bit Zahl angegeben und das Ergebnis als 16-Bit-Zahl berechnet. Ein eventueller Überlauf wird nicht beachtet.
Der Code wird jeweils als eigene Funktion implementiert, um Abhängigkeiten vom umliegenden Code zu vermeiden.
Für diese Berechnung gibt es mehrere Möglichkeiten.
Aufsummieren in einer Schleife
Quellcodes:
|
|
Compilat:
|
|
Berechnung mit rekursiver Funktion
Quellcodes:
|
|
Compilat:
|
|
Berechnung durch Formel
Quellcodes:
|
|
Compilat:
|
|
Interrupt-Routinen
Auch diese Beispiele machen nicht viel. Das erste zählt nur eine 16-Bit Variable hoch, das zweite macht nichts weiter, als ein Funktionsaufruf.
Eine Variable hochzählen
Quellcodes:
|
|
Compilat:
|
|
Eine Funktion aufrufen
Quellcodes:
|
|
Compilat:
|
|