Wie gewünscht ein eigener Beitrag zum Thema Vergleichen von Werten mit dem passenden Branch Befehl.
Ich habe mir hierzu mal eine Tabelle angelegt, die mir immer sehr hildreich ist, um nicht bei jedem Vergleich wieder von vorne nachdenken zu müssen:
Ist A kleiner als B?
LDA A
CMP B
BCC -> Ja A<B
Ist A kleiner oder gleich als B?
LDA B
CMP A
BCS -> Ja A<=B
Ist A größer als B?
LDA B
CMP A
BCC -> Ja A>B
Ist A größer gleich als B?
LDA A
CMP B
BCS -> Ja A>=B
CMP/BCx
Moderator: Rockford
Online
- Olix
- Beiträge: 1081
- Registriert: 17.08.2021 07:06
- Has thanked: 130 times
- Been thanked: 469 times
- Kontaktdaten:
Re: CMP/BCx
... nur der Vollständigeit wegen:
Ist A gleich B?
LDA A
CMP B
BEQ -> Ja A=B
Ist A ungleich B?
LDA A
CMP B
BNE -> Ja A<>B
Noch eine kleine Erklärung:
Der CMP Befehl macht eigentlich nichts anderes als den Vergleichswert vom Akku zu subtrahieren ohne aber das Ergebnis zu speichern. Sehr wohl werden aber die enstprechenden Flags für das Ergebnis gesetzt, entsprechend dem SBC-Befehl. Also das N,Z,C oder/und V Flag (Ein SEC Befehl vor dem CMP ist übrigens nicht notwendig)
Jetzt kann man sich leicht die entsprechenden Branch-Befehle herleiten:
Sind z.B. beide Werte gleich, so ergibt die interne Subtraktion ja Null. Das Ergebnis wird zwar verworfen , aber das Zero-Bit wird gesetzt und kann somit mit BEQ und BNE (also Null oder Nicht-Null) abgefragt werden.
Ist der Wert im Akku kleiner dem Vergleichswert, so ist das Ergebnis der simulierten Subtraktion negativ und somit ist das N-Flag gesetzt. Also wäre hier der Branch Befehl BMI (Sprung wenn Minus)
Alle anderen Vergleichsabfragen kann man sich jetzt leicht herleiten ...
Ist A gleich B?
LDA A
CMP B
BEQ -> Ja A=B
Ist A ungleich B?
LDA A
CMP B
BNE -> Ja A<>B
Noch eine kleine Erklärung:
Der CMP Befehl macht eigentlich nichts anderes als den Vergleichswert vom Akku zu subtrahieren ohne aber das Ergebnis zu speichern. Sehr wohl werden aber die enstprechenden Flags für das Ergebnis gesetzt, entsprechend dem SBC-Befehl. Also das N,Z,C oder/und V Flag (Ein SEC Befehl vor dem CMP ist übrigens nicht notwendig)
Jetzt kann man sich leicht die entsprechenden Branch-Befehle herleiten:
Sind z.B. beide Werte gleich, so ergibt die interne Subtraktion ja Null. Das Ergebnis wird zwar verworfen , aber das Zero-Bit wird gesetzt und kann somit mit BEQ und BNE (also Null oder Nicht-Null) abgefragt werden.
Ist der Wert im Akku kleiner dem Vergleichswert, so ist das Ergebnis der simulierten Subtraktion negativ und somit ist das N-Flag gesetzt. Also wäre hier der Branch Befehl BMI (Sprung wenn Minus)
Alle anderen Vergleichsabfragen kann man sich jetzt leicht herleiten ...
- Kveldulfur
- Beiträge: 645
- Registriert: 17.08.2021 02:32
- Has thanked: 248 times
- Been thanked: 171 times
- Kontaktdaten:
Re: CMP/BCx
Schleife von 5 bis 1
Schleife von 5 bis 0
Für NOP natürlich den eigenen Code einsetzen
BNE verzweigt wenn das letzte Ergebnis nicht 0 war.
BPL verweigt wenn das letzte Ergebnis positiv war.
Code: Alles auswählen
LDX #5
Loop: NOP
NOP
DEX
BNE Loop
Code: Alles auswählen
LDX #5
Loop: NOP
NOP
DEX
BPL Loop
BNE verzweigt wenn das letzte Ergebnis nicht 0 war.
BPL verweigt wenn das letzte Ergebnis positiv war.
Online
- Olix
- Beiträge: 1081
- Registriert: 17.08.2021 07:06
- Has thanked: 130 times
- Been thanked: 469 times
- Kontaktdaten:
Re: CMP/BCx
Und entsprechend noch in die andere Richtung von 1 bis 5:
BNE verzweigt solange X nicht den Wert 6 hat.
Da die Inkrementierung am Ende der Schleife erfolgt ist der Vergleichswert um 1 höher dem gewünschten Ziel.
Code: Alles auswählen
LDX #1
LOOP: NOP
NOP
INX
CPX #6
BNE LOOP
Da die Inkrementierung am Ende der Schleife erfolgt ist der Vergleichswert um 1 höher dem gewünschten Ziel.
Online
- Olix
- Beiträge: 1081
- Registriert: 17.08.2021 07:06
- Has thanked: 130 times
- Been thanked: 469 times
- Kontaktdaten:
Re: CMP/BCx
... und noch eine Schleife von 0 bis 255:
Die Schleife wird beendet sobald der Wert nach der Inkrementierung wieder 0 ist
Code: Alles auswählen
LDX #0
LOOP: NOP
NOP
INX
BNE LOOP
- Dr. Irata
- Beiträge: 946
- Registriert: 24.08.2021 14:40
- Has thanked: 113 times
- Been thanked: 275 times
- Kontaktdaten:
Re: CMP/BCx
Eine kleine Ergänzung habe ich hier auch noch:
MADS bietet ja die Funktion #If .and .or #End an.
Ich persönlich mag diese Funktion, da sie sehr einfach zu lesen ist und übersichtlich und schnell programmiert ist.
Leider ist der Code nicht wirklich optimiert - eine gleiche Funktion erreicht man durch CMP / BCC / BCS mit fast der Hälfte des Codes und entsprechend Geschwindigkeitsgewinn... zur Übersicht habe ich mal den Code für eine If And - Anweisung:
In MADS:
wird zu:
und dann in MADS:
wird zu:
Zur besseren Übersicht habe ich hier extra eine Variable (var1) mit Werten verglichen, man kann natürlich auch statt der Werte weitere Variablen einsetzen.
MADS bietet ja die Funktion #If .and .or #End an.
Ich persönlich mag diese Funktion, da sie sehr einfach zu lesen ist und übersichtlich und schnell programmiert ist.
Leider ist der Code nicht wirklich optimiert - eine gleiche Funktion erreicht man durch CMP / BCC / BCS mit fast der Hälfte des Codes und entsprechend Geschwindigkeitsgewinn... zur Übersicht habe ich mal den Code für eine If And - Anweisung:
In MADS:
Code: Alles auswählen
#if .byte var1<#10
.... hier steht der Code ....
#end
Code: Alles auswählen
lda var1
cmp #10
bcs weiter
.... hier steht der Code ....
weiter
Code: Alles auswählen
#if .byte var1>=#120 .and var4<#240
.... hier steht der Code ....
#end
Code: Alles auswählen
lda var1
cmp #120
bcc weiter
cmp #240
bcs weiter
.... hier steht der Code ....
weiter
- LarsImNetz
- Beiträge: 156
- Registriert: 24.08.2021 18:27
- Has thanked: 114 times
- Been thanked: 84 times
- Kontaktdaten:
Re: CMP/BCx
Vielen Dank Olix für die Tipps.
BTW: http://6502.org/tutorials/compare_beyond.html ist ein sehr schöner Artikel dazu, wer ein wenig tiefer in die Materie einsteigen möchte. Gerade mit vorzeichenbehafteten Zahlen sei es 8 oder 16 bit wird es echt komisch.
Wer nur auf var1 auf 0 prüfen möchte:
in 16 bit
Lars
BTW: http://6502.org/tutorials/compare_beyond.html ist ein sehr schöner Artikel dazu, wer ein wenig tiefer in die Materie einsteigen möchte. Gerade mit vorzeichenbehafteten Zahlen sei es 8 oder 16 bit wird es echt komisch.
Wer nur auf var1 auf 0 prüfen möchte:
Code: Alles auswählen
lda var1
beq sprung_wenn_var1_ist_0
Code: Alles auswählen
lda var1
ora var1+1 ; hier werden beide Teile der Zahl zusammen geodert.
beq sprung_wenn_var1_ist_0
Wer ist online?
Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast