AVR-Tutorial: Vergleiche

Aus der Mikrocontroller.net Artikelsammlung, mit Beiträgen verschiedener Autoren (siehe Versionsgeschichte)
Wechseln zu: Navigation, Suche

Vergleiche und Entscheidungen sind in jeder Programmiersprache ein zentrales Mittel um den Programmfluss abhängig von Bedingungen zu kontrollieren. In einem AVR spielen dazu 3 Komponenten zusammen:

  • Vergleichsbefehle
  • die Flags im Statusregister
  • bedingte Sprungbefehle

Der Zusammenhang ist dabei folgender: Die Vergleichsbefehle führen einen Vergleich durch, zum Beispiel zwischen zwei Registern oder zwischen einem Register und einer Konstante. Das Ergebnis des Vergleiches wird in den Flags abgelegt. Die bedingten Sprungbefehle werten die Flags aus und führen bei einem positiven Ergebnis den Sprung aus. Besonders der erste Satzteil ist wichtig! Den bedingten Sprungbefehlen ist es nämlich völlig egal, ob die Flags über Vergleichsbefehle oder über sonstige Befehle gesetzt wurden. Die Sprungbefehle werten einfach nur die Flags aus, wie auch immer diese zu ihrem Zustand kommen.


Vergleiche

Um einen Vergleich durchzuführen, wird intern eine Subtraktion der beiden Operanden durchgeführt. Das eigentliche Ergebnis der Subtraktion wird allerdings verworfen, es bleibt nur die neue Belegung der Flags übrig, die in weiterer Folge ausgewertet werden kann

CP - Compare

Vergleicht den Inhalt zweier Register miteinander. Prozessorintern wird dabei eine Subtraktion der beiden Register durchgeführt. Das eigentliche Subtraktionsergebnis wird allerdings verworfen, das Subtraktionsergebnis beeinflusst lediglich die Flags.

CPC - Compare with Carry

Vergleicht den Inhalt zweier Register, wobei das Carry Flag in den Vergleich mit einbezogen wird. Dieser Befehl wird für Arithmetik mit grossen Variablen (16/32 Bit) benötigt. Siehe AVR-Tutorial: Arithmetik.


Bedingte Sprünge

Die bedingten Sprünge werten immer bestimmte Flags im Statusregister SREG aus. Es spielt dabei keine Rolle, ob dies nach einem Vergleichsbefehl oder einem sonstigen Befehl gemacht wird. Entscheidend ist einzig und alleine der Zustand des abgefragten Flags. Die Namen der Sprungbefehle wurden allerdings so gewählt, daß sich im Befehlsnamen die Beziehung der Operanden direkt nach einem Compare Befehl wiederspiegelt. Zu beachten ist auch, daß die Flags nicht nur durch Vergleichsbefehle verändert werden, sondern auch durch arithmetische Operationen, Schiebebefehle und logische Verknüpfungen. Da dieses Information wichtig ist, ist auch in der bei Atmel erhältlichen Übersicht über alle Assemblerbefehle bei jedem Befehl angegeben, ob und wie er Flags beeinflusst. Ebenso ist dort eine kompakte Übersicht aller bedingten Sprünge zu finden. Beachten muss man jedoch, dass die bedingten Sprünge maximal 64 Worte weit springen können.

Bedingte Sprünge für vorzeichenlose Zahlen

BRSH - Branch if Same or Higher

Der Sprung wird durchgeführt, wenn das Carry Flag (C) nicht gesetzt ist. Wird dieser Branch direkt nach einer CP, CPI, SUB oder SUBI Operation eingesetzt, so findet der Sprung dann statt, wenn der erste Operand größer oder gleich dem zweiten Operanden ist.

BRLO - Branch if Lower

Der Sprung wird durchgeführt, wenn das Carry Flag (C) gesetzt ist. Wird dieser Branch direkt nach einer CP, CPI, SUB oder SUBI Operation eingesetzt, so findet der Sprung dann statt, wenn der erste Operand kleiner dem zweiten Operanden ist.

Bedingte Sprünge für vorzeichenbehaftete Zahlen

BRGE - Branch if Greater or Equal

Der Sprung wird durchgeführt, wenn das Signed Flag (S) nicht gesetzt ist. Wird dieser Branch direkt nach einer CP, CPI, SUB oder SUBI eingesetzt, so findet der Sprung dann und nur dann statt, wenn der zweite Operand größer oder gleich dem ersten Operanden ist.

BRLT - Branch if Less Than

Der Sprung wird durchgeführt, wenn das Signed Flag (S) gesetzt ist. Wird dieser Branch direkt nach einer CP, CPI, SUB oder SUBI Operation eingesetzt, so findet der Sprung dann und nur dann statt, wenn der zweite Operand kleiner als der erste Operand ist.

BRMI - Branch if Minus

Der Sprung wird durchgeführt, wenn das Negativ Flag (N) gesetzt ist, das Ergbnis der letzen Operation also negativ war.

BRPL - Branch if Plus

Der Sprung wird durchgeführt, wenn das Negativ Flag (N) nicht gesetzt ist, das Ergbnis der letzen Operation also positiv war (einschiesslich Null).

Sonstige bedingte Sprünge

BREQ - Branch if Equal

Der Sprung wird durchgeführt, wenn das Zero Flag (Z) gesetzt ist. Ist nach einem Vergleich das Zero Flag gesetzt, lieferte die interne Subtraktion also 0, so waren beide Operanden gleich.

BRNE - Branch if Not Equal

Der Sprung wird durchgeführt, wenn das Zero Flag (Z) nicht gesetzt ist. Ist nach einem Vergleich das Zero Flag nicht gesetzt, lieferte die interne Subtraktion also nicht 0, so waren beide Operanden verschieden.

BRCC - Branch if Carry Flag is Cleared

Der Sprung wird durchgeführt, wenn das Carry Flag (C) nicht gesetzt ist. Dieser Befehl wird oft für Arithmetik mit grossen Variablen (16/32 Bit) bzw. im Zusammenhang mit Schiebeoperatioen verwendet.

BRCS - Branch if Carry Flag is Set

Der Sprung wird durchgeführt, wenn das Carry Flag (C) gesetzt ist. Die Verwendung ist sehr ähnlich zu BRCC.

Selten verwendete bedingte Sprünge

BRHC - Branch if Half Carry Flag is Cleared

Der Sprung wird durchgeführt, wenn das Half Carry Flag (H) nicht gesetzt ist.

BRHS - Branch if Half Carry Flag is Set

Der Sprung wird durchgeführt, wenn das Half Carry Flag (H) gesetzt ist.

BRID - Branch if Global Interrupt is Disabled (Cleared)

Der Sprung wird durchgeführt, wenn das Interrupt Flag (I) nicht gesetzt ist.

BRIS - Branch if Global Interrupt is Enabled (Set)

Der Sprung wird durchgeführt, wenn das Interrupt Flag (I) gesetzt ist.

BRTC - Branch if T Flag is Cleared

Der Sprung wird durchgeführt, wenn das (T) nicht gesetzt ist.

BRTS - Branch if T Flag is Set

Der Sprung wird durchgeführt, wenn das (T) gesetzt ist.

BRVC - Branch if Overflow Cleared

Der Sprung wird durchgeführt, wenn das Overflow Flag (V) nicht gesetzt ist.

BRVS - Branch if Overflow Set

Der Sprung wird durchgeführt, wenn das Overflow Flag (V) gesetzt ist.

Beispiele