Computer-Basiswissen 2         

von Otmar Feger              

Elektronik-Labor
 Literatur  Projekte  Lernpakete  Basiswissen



Programmablaufsteuerung
Wird ein Befehl aus dem Befehlsspeicher abgeholt, muss die Programmablaufsteuerung diesen entschlüsseln. Das geschieht durch einen Festwertspeicher der einzelnen Signale nebeneinander und oder nacheinander erzeugt um die Befehlsausführung durchzuführen. Dieser Festwertspeicher nennt man das Mikroprogramm.

Wie Befehle im Einzelnen im Computer ablaufen zeigt Bild 12 in einer vereinfachten Darstellung. Zuerst erklären wir die Komponenten der Schaltung.
Auf der linken Bildseite sehen Sie den Taktgenerator, der den Befehlszähler steuert. Die Länge eines Befehlszählers entspricht dem Adressraum des Programm- und Datenspeichers Bei 16 Zählstufen lassen sich bis 65.535 Befehle ansteuern. Dieser Speigrößen können nur teilweise integriert sein, sie sind jedoch  extern anschließbar. Heute üblich Taktraten liegen zwischen 12 und 50 MHz.

Beim Programmstart steht der Befehlszählerinhalt auf Null, und der Inhalt des ersten Befehls wartet darauf an den Mikroprogrammspeicher übergeben zu werden. Die ersten Stufen des Befehlszählers steuern den Mikroprogrammspeicher an. Dieser erzeug dann in zeitlicher Reihenfolge die Signale die zur Ausführung des aktuellen Befehls erforderlich sind. An schließend greift der Befehlszähler auf den nächsten Befehl zu und der Zyklus wiederholt sich. Die Befehlszyklenzeit ist also niederer als die Taktrate. Beträgt die Taktrate z. B. 12 MHz (8051) so ist die Befehlszyklenzeit 1 MHz. Das sind immerhin eine Million Befehle je Sekunde.

Die parallelen Verbindungen zwischen den Controller-Einheiten nennt man einen Bus, In Bild  12 sind sie graphisch zusammen gefasst, auch wegen der einfacheren bildlichen Darstellung.. Es gibt Adress-, Daten- und Steuerbusse. An einem Befehl sei der weitere Ablauf erläutert.

   MOV    AUSGABE_1,ADRESSE_1000
 ; Transportbefehl: Bringe Inhalt der der Adresse 1000 aus dem Datenspeicher  zur  <Ausgabeeinheit 1>

MOV ist die englische Bezeichnung für Bewegung, AUSGABE_1 ist der Ausgabe-Port 1 und nach dem Strichpunkt dem folgt ein Kommentar. Die Reihenfolge der Ausdrücke von links nach rechts stammt wohl von den Mathematikern, die ihre Gleichungen so schreiben und bei den Computerentwicklungen mitarbeiteten. Bei der Programmierung wird viel mit Symbolen gearbeitet, Befehle, Daten und Adressen sind als Symbole zu vereinbaren. Das lässt Programme leichter schreiben und lesen.



Software

Wie schon erwähnt arbeitet man mit Assemblern. Jedem Befehl bekam eine Buchstabenkombination die ihm eine eindeutige Bedeutung zugeordnete. (MUL, DIV, MOV usw.). Wichtig war, dass man Symbole für Marken Adressen und Konstanten einführte. Marken bestimmten Sprungziele von Unterprogrammen, Interrupts oder Zeilen in der Programmliste um die Bedeutung von Programmteilen zu kennzeichnen. Zu jedem Befehl kann auch ein Kommentar hinzugefügt werden.

Es gibt auf der untersten Programmebenen mehrere Befehlskategorien: Transportbefehle (MOV), Set- und Löschbefehle, Arithmetik- und Logikbefehle (ADD, SUBB, MUL, DIV – OR, AND), Sprungbefehle zur Programmsteuerung (SET, CLR), Vergleichsbefehle (> < =), Bitverarbeitungsbefehle und Befehle aus zusammengesetzten Fumktionen.



Bild 16 zeigt den Ausschnitt eines solchen Programms. Über die Details braucht man sich zunächst keine Gedanken machen. Auf der linken Seite sind einige Marken als Sprungziele oder zur Kennzeichnung. Die Befehle (zuerst der Operationscode und dann der Adressteil) befinden sich in der nächsten Spalte. Am rechten Rand sind, durch „Strichpunkt“ getrennte Kommentare möglich.

Der Assembler ordnet allen Symbolen Befehlen, Daten oder Konstanten zu, prüft auf logische und Syntaxfehler und gibt bei Fehlerfreiheit ein ablauffähiges Programm  aus. Besondere Befehle, die mehrere Funktionen ausführen werden hier kurz beschrieben.

Indexbefehle
Indexregistern sind Register die eine indirekte Programmierung erlauben. Das bedeutet der Inhalt des Indexregisters zeigt auf eine Adresse auf die man über das Indexregister zugreifen kann. Eine häufige Anwendung ist das Durchlaufen einer Liste. Der Inhalt des Indexregisters steht auf dem Listenanfang. Über das Index-Register kann nun mit einem Befehl auf die Liste zugegriffen werden, z. B. Lade den Inhalt aus der Adresse auf die das Index hinweist in den Akkumulator. Erhöht man der Inhalt des Indexregisters jeweils um 1, kann man auf diese Art innerhalb einer Programmschleife die Liste durchlaufen.

Vermindere eine Zahl um 1 und Springe wenn das Inhalt gleich 0
Dieser Befehle ist besonders bei Zählschleifen nützlich, um solange zu Verzweigen bis der Wert 0 erreicht ist.

Vergleiche den Inhalt des Akkumulators mit einer Zahl oder dem Inhalt eines direkt oder indirekt adressierten  Speicherplatzes.
    Besonders nützlich bei der Lösung von Suchaufgaben.

Unterprogrammsprünge und Interruptspünge
Auf Sprünge in ein Unterprogramm und auf Sprünge die ein Interrupt auslöst  sei hier näher eingegangen. Benötigt man bestimmte Programmteile mehrfach, sind diese nicht mehrfach zuschreiben. Solle eine Division mit beispielsweise 32 bit große Zahlen von einem Mikrocontroller mit 8 bit Verarbeitungsbreite durchgeführt werden ist dazu ein eigenes Programm erforderlich. Legt man diesen in ein Unterprogramm so kann es von beliebig vielen Stellen beliebig oft vom Hauptprogramm aus aufgerufen werden. Ein solches Unterprogramm kann sehr umfangreich sein. Das Unterprogramm endet mit dem Rücksprung an die Adresse, die nachdem Unterprogrammaufruf folgt. Unterprogrammen erlauben erst die Bildung höherer Programmiersprachen da sie beliebige Inhalte, also auch Sprachkonstrukte, enthalten können. Durch die Möglichkeit der Verschachtelung sind beliebig viele Ebenen denkbar.



Ein Interrupt ist ein Sprungbefehl der ein internes oder externes Ereignis auslöst. Interne Ereignisse mögen Überläufe integrierter Zähler/Zeitgeber, Abschluss einer internen A/D-Wandlung sein. Ursachen für externe Interrupts können z. B. Signalwechsel an einem Eingangspin sein. Beispielsweise löst ein Regensensor nach einem Millimeter Niederschlag einen Interrupt aus der dann im Interrupt-Programm einen Zäher inkrementieret (+1), eventuell auf das Erreichen eines Schwellwerts abfragt und dann an die vorher unterbrochenen Stelle zurückkehrt. Ein anderes Beispiel ist die Meldung einer Seriellen Schnittstelle um ein ankommendes Signal anzukündigen.

Da die meisten Mikrocontroller mehrere verschiedene Interrupte zulassen, kann man den einzelnen Interrupt-Quellen unterschiedliche Prioritäten zuweisen. Das Hauptprogramm verbietet oder erlaubt bei Bedarf einzelne oder alle Interrupts. Bild 14 veranschaulicht die Verhältnisse bei Unterprogrammen und Interrupts.. Die Sprünge sind blau, die Rücksprünge gelb markiert.

Weitere Programmsteuerbefehle
Bei Unter- und Interruptprogrammen kann man davon ausgehen, dass das unterbrochene Programm verschiedene Register in Daten geladen hat, die nicht verloren gehen dürfen. Deshalb gibt es spezielle Befehle die die fraglichen Registerinhalte am Anfang in einen besonderen Teil des Datenspeicher (dem Stack) ablegen und am Ende der Unter- und Interrupt-Programme wieder aus dem Stack zurückholen.

Außer dem Assemblerprogramm gibt es weitere Programme, um die Programmierarbeit zu unterstützen. Der Linker fasst mehrere Assemblerprogramme zusammen. Sei es, um vorhandene Programmteile einzubinden oder dass mehrere Programmierer gleichzeitig an einer gemeinsamen Aufgabe arbeiten Der Simulator erlaubt Programmabläufe schritt- oder teilweise zu durchlaufen und damit alle Details nachzuvollziehen. Zur Fehlersuche nahezu unverzichtbar. Es gibt auch Ladeprogramme, die ein Programm unmittelbar in einen Controller oder ein EPROM speichern. Ein EPROM ist ein extern anschließbarer Speicher dessen Inhalt durch UV-Licht löschbar ist. Es gibt auch Controller mit integriertem EPROM, Diese sind jedoch teuer. In einer größeren Serienproduktion (etwa ab einigen 1000 Stück) werden Programme unmittelbar auf den Chip mitintegriert.

Die Mikrocontroller verschiedener Firmen haben Architekturen mit eigenen Befehlssätzen und Benennungen. Es ist also jeweils ein eigener Assembler erforderlich. Um von Rechnertypen unabhängig zu sein entwickelte man zuerst bei den Großrechnern rechnerunabhängige Programmsprachen deren Übersetzung die auf allen Rechnertypen lauffähig waren. Die Programme, die diese Sprachen in die jeweiligen Computer übersetzten nennt man Compiler. So gab es beispielsweise COBOL für kaufmännische und FORTRAN für mathematische Anwendungen Es folgten eine ganze Reihe weitere, verbesserte Sprachen. In gleicher Weise entwickelte man für Mikrocontroller das Programm BASIC. BASIC-Compiler mussten ebenfalls an das jeweilige Assemblerprogramm angepasst werden. Nachfolger von BASIC war dann die Sprache C. Unterschiedlichen Mikrocontroller-Typen benötigen jeweils eigene Compilerprogramme.

Höhere Programmiersprachen bringen für den Programmierer viele Vereinfachungen. So musste er sich z. B. nicht mehr um Wortlängen kümmern und es entfallen viele Transportbefehle da Kommandos in höheren Sprachen sich meistens aus vielen Assemblerbefehlen zusammensetzten.  Höhere Programmiersprachen sind jedoch hier nicht das Thema.

Es folgen einige typische Programmierbeispiele um die Vorgehensweise darzulegen.

Beispiel 1; Aus drei Zahlen die größte ermitteln und abspeichern

Wie schon erwähnt arbeiten Programme die Befehle nacheinander ab. Es sollen die größte aus drei Zahlen A_ZAHL, B_ZAHL und C_ZAHL, ermittelt und das Ergebnis in D_ZAHL gespeichert werden. In Programmen kann und soll man komplizierte Sachverhalte durch Flussdiagramme darstellen. Sie dienen der Dokumentation der Vergehensweise damit man den Sachverhalt später nicht durch die einzelnen Befehle nachvollziehen muss. Nach längerer Zeit weiß sowieso nicht mehr, was man sich damals gedacht hat. Das Beispiel ist für die Praxis unbedeutet. Da sich aber jeder etwas darunter vorstellen kann eignet es sich besonders zur Darstellung der Programmiermethode. Bild 15 zeigt das Flußdiagramm und Bild 16 das Programm dazu.






Der Akkumulator (AKKU) ist das rechenfähige Register, das auch Größer-/Kleiner-Vergleiche mittels des Subtraktions-Befehls SUBB  ermöglicht.
Inhalt von Adressen werden in eckige Klammern geschrieben, z. B. <Alpha>, Die Adresse selbst, z. B. von  (Alpha) wird mit offenen Klammern eingerahmt, >Alpha<.

Beispiel 2:  Löschen eines Speicherbereichs
Viel häufiger hat man mit Listen zu tun. Beispielsweise um etwas zu suchen oder zu sortieren. Das hier beschriebene Beispiel lässt sich mit wenigen Befehlen dazu anpassen  (Bilder 17 und 18).







Beispiel 3:  Uhrzeiten programmieren
Vorgehendweise und Voraussetzungen fassen die Bilder 19 bis 21 zusammen. Die Bilder 22 bis 24 zeigen dazu das Flussdiagramm. Ein integrierter Zähler ist so konfiguriert, dass er alle Millisekunde überläuft und einen Interrupt auslöst. Danach wiederholt sich der Zyklus. Das Interrupt-Progamm wird also jede Millisekunde aufgerufen und ermittelt die verschiedenen Uhrzeiten.














Zusammenfassung
Durch die Unterprogrammtechnik sind beliebige Programme in ein Unterprogramm einzubinden. Der Name des Unterprogramms kann gleichsam als eigener Befehl aufgefasst werden. Auf diese Weise lassen sich ganz neue Befehlssätze entwickeln die auf verschieden Anwendungsaufgaben anzupassen sind. So wird beispielsweise ein Malprogramm andere Befehle als ein Fahrplan oder Textprogramm benötigen. Üblicherweise gibt es dann mehrere Ebenen (Abstraktionen) übereinander angeordnet Programme um komplexe Aufgaben lösen zu können.

PC Programmieren
Bei Programmen die auf PC laufen sollen hat der Programmierer eine andere Situation vor sich als in der Mikrocontroller-Welt. Nach dem Einschalten eines PC startet automatisch das Programm BIOS (Basis Imput Output System). Dieses stellt die grundsätzlich Verbindung mit Tastatur, der Maus, den Speicherlaufwerken (Festplatten und Disks), Bildschirm und den externen Schnittstellen her. Das ist die erste und unterste Programmebene. Das dann geladene Betriebssystem stellt die zweite Ebene dar. Das Betriebssystem, meistens Windows, lädt aus einer eine Vielzahl externer Peripheriegeräten wie Tastaturen, Drucker, Bildschirme und Graphikkarten, sowie viele andere extern Geräte, Treiber, die die Lieferanten dieser Geräte zur Verfügung stellen.
Zudem stell das Betriebssystem leistungsstarke Werkzeuge zur Verfügung, um die Arbeit des Programmierers  zu erleichtern. Genannt sei die Fenstertechnik, Schriften,  Farbenverwaltung und Interanbindung aber auch interne Archivverwaltungen usw.. Auf das Betriebssystem setzt dann das Anwenderprogramm als dritte Ebene auf. Innerhalb diesem gibt es naturgemäß wieder weitere Ebenen (Bild 25).



Stellen wir uns das vereinfachte Vorgehen eines Programmierers beim Entwickeln eines Graphik-Programms vor. Zuerst listete er die Werkzeuge (Tools) die dem Zeichner zu Verfügung stehen müssen auf. Er stellt sie auf dem Bildschirm als Symbole (Icons) dar die man mit der Maus oder der Tastatur aktivieren kann. Beispielsweise Strecken, Kreise, Vierecke, Strichstärken, Farbauswahl, Kopier und Löschfunktionen usw. Das ist seine untere Programmebene. Jedes Icon führt zu einem Unterpogramm das den entsprechenden Befehl ausführt und das Ergebnis auf dem Bildschirm darstellt. Diese Unterprogramme sind teilweise sehr komplex und benötigen wiederum eigene Ebenen. Nach dem Prinzip Eingabe, Verarbeiten und Ausgabe arbeiten die meisten Programme.

Ausblick
Auf der Hardware-Seite steht die Leistungssteigerung im Vordergrund. Dabei spielen Multi-Rechnerkerne eine zunehmende Rolle. So wie man bei den PC zur Leistungserhöhung, beispielsweise bei Google, Systeme mit vielen 1000 PC vernetzte um leistungsfähige Suchalgorithmen zu realisieren. Diese überwachen sich gegenseitig und schalten fehlerhafte Teile ab ohne den Betrieb zu stören (Fehlertolerant). Mikrocontroller mit bis zu 8 Rechnerkernen für spezielle Anwendungen wurden ebenfalls entwickelt.

Multirechnerkerne analysieren und verarbeiten den aktuellen Befehlsdurchsatz oder die Befehlsfolgen, um sie so weit wie möglich in Teile zu zerlegen, parallel abzuarbeiten und damit den Befehlsdurchsatz zu beschleunigen. Die PC-Taktgeschwindigkeiten reichten inzwischen bis in den Gigaherzbereich,  (1.000.000.000 = 1 Giga). Speicher ereichten Kapazitäten mehrer Terrabytes Das sind noch mal drei Nullen mehr.

Auf der untersten Ebene das Assemblerprogramm, dann das Betriebssystem und dann das compilierte Anwenderprogramm, Je nach Anwendungsbereich folgen die Ebenen  eines Textverarbeitungs- oder Graphikprogramm, einem Datenbanksystem zur Lagerverwaltung, ein Bank- oder ein Klinikverwaltungssystem usw. Man spricht da von Schichtenmodellen oder Abstraktionsebenen. Der Computer ist ein Werkzeug mit unbegrenzten Möglichkeiten. Es wird einmal möglich sein, dass er für Problemebereiche selbstständig Lösungen sucht und dann dazu die passenden Programme selbst schreibt. 

zurück: Teil 1

 


Elektronik-Labor  Literatur  Projekte  Lernpakete  Basiswissen