Eine wichtige Errungenschaft von CPUs sind Flaggen !
Diese Übersetzung findet sich in der deutschen Ausgabe von Rodney Zaks Klassiker. Gemeint sind natürlich keine Fahnen oder Wimpel sondern "Flags". Eine schönere Übersetzung wäre vielleicht Warnlampen oder Informationsleuchtpult.
Real sind Flags natürlich keine Lampen oder Flaggen, sondern bestimmte Bits an einer bestimmten immer gleichen Stelle, die ein oder ausgeschaltet werden.
So eine CPU macht nicht nur verschiedenes, sie signalisiert auch, wenn bestimmte Umstände eintreten. Ein Beispiel war bereits öfters erwähnt worden, immer dann wenn ein Überlauf eintritt, wird das von der CPU bemerkt und "gemeldet", d.h. an einer bestimmten Stelle signalisiert (nämlich im sogenannten Überlauf Flag).
Welche Dinge eine bestimmte CPU insgesamt überwacht, hängt nun wieder vom Modell ab. Manches wird evtl. intern auch bemerkt, aber nicht nach außen mitgeteilt, d.h. mittels Flag mitgeteilt.
Außerdem ist es auch noch so, daß gar nicht alle Befehle wirklich alle Flags beeinflussen können. Damit man da den Überblick nicht verliert gibt es dann wieder Tabellen. Es bedeutet für den Programmierer, daß er aufpassen muß, ob das Flag, was er abfragen möchte überhaupt von dem Befehl beeinflußt wird, den er schreiben möchte.
Meist ist es so, daß einfach der letzte Befehl, der gerade ausgeführt worden ist, die Flags verändert hat und im Anschluß schaut man dann nach, ob ein bestimmtes Flag nun gesetzt ist oder nicht. In Abhängigkeit davon, wie der Flag-Zustand des interessierenden Flags dann gerade ist, macht man evtl. an einer anderen Stelle im Programm weiter.
Welche Umstände in der CPU sind nun so besonders, daß es lohnt sie zu melden ?
Eigentlich alle bei denen eine Zahl die gerade bearbeitet wurde einen besonderen Wert annimmt.
Oft sind das
- Überläufe - wenn also das "Zahlrädchen" (Register) vom maximalen Wert auf Null (oder noch weiter) weitergezählt wurde, das Register also überläuft
- Vorzeichenwechsel - wenn eine Zahl, die gerade so betrachtet wird, daß sie auch negative Zahlen darstellen kann, von + nach - wechselt
- Rechenoperationen, bei denen im Ergebnis eine Zahl herauskommt, die einen Übertrag in die nächste Stelle erfordert
und ganz wichtig
- wenn in einem Register oder bei der letzten CPU Arbeit eine 0 (Null) entstanden ist
Dieses Flag, was bemerkt, ob da eine 0 da war, nennt man das Zero-Flag !
Wenn also etwas ein Register mit dem Wert 0 geladen wird ( LADE Register(Name) $00 ), wird i.a. automatisch auch die Null-Flagge, das Zero-Flag, gesetzt.
Wenn man beim Weiterzählen eines Registers wieder bei Null ankommt, weil die Zahlenmenge quasi komplett durchgezählt ist, wird auch das Zero-Flag gesetzt.
Wenn man zwei Zahlen miteinander vergleicht und beide den gleichen Wert haben, wird das Zero-Flag gesetzt.
Es gibt auch CPUs bei denen man bei jedem Befehl entscheiden kann, ob die Flags beeinflußt werden oder nicht. Bei vielen anderen macht die CPU das automatisch ohne Nachfrage. Was dafür dann aber bei manchen Flags geht, ist, daß man sie gezielt selber ein- oder ausschalten kann. (etwa das Carry Flag oder das Interrupt Flag)
Wozu ist das nun gut ?
Es erlaubt einem Fallunterscheidungen zu machen und auch auf die besonderen Zustände der Zahlen/Register zu reagieren.
Wie das geschieht hängt wieder von der CPU ab. Die ARM CPUs haben hier z.B. eine ihrer ganz großen Stärken, indem sie nämlich i.P. die Ausführung eines jeden Befehls davon abhängig machen können, ob ein bestimmtes frei wählbares Flag gesetzt ist oder eben nicht.
Bei anderen CPUs gibt es Sprungbefehle, die nur dann einen Sprung ausführen, wenn das zugehörige Flag gesetzt ist. Damit kann man dann den Programmablauf woanders fortsetzen, wenn das Flag "an" war. Meist gibt es daneben auch noch einen weiteren Sprungbefehl, der nur dann ausgeführt wird, wenn das zu ihm gehörende Flag "aus" war.
Das sieht also so aus
Flag ---> GESETZT ? ANGESCHALTET ? ---> Springe nach Adresse $Flag-ist-ON
Flag ---> AUSGESCHALTET ? ---> Springe nach $Flag-ist-OFF
( Es gibt dabei auch Sprungbefehle, die mehrere solche Flags in einer Anweisung zusammen abfragen. Solches Verhalten läßt sich aber auch aus einfachen Einzelflagabfragen zusammenbauen, wenn man mehrere solche hintereinander ausführt.)
Die Flags selber werden in einem sogenannten Statusregister gespeichert. Natürlich nur solange, bis sich wieder ein Flag ändert, was bereits beim nächsten Befehl passieren kann.
Da die Flags ja unmittelbar Auskunft über die letzte Operation geben, kann es manchmal sehr wichtig sein, dieses Statusregister (also alle Flags auf einmal) woanders abzuspeichern. Vor allem dann, wenn man erstmal was anderes rechnen will und später aber an exakt der aktuellen Stelle weitermachen möchte (etwa bei einem Interrupt oder einer Unterfunktion).