CMP/BCx

Moderator: Rockford

Antworten
Benutzeravatar
Olix
Beiträge: 987
Registriert: 17.08.2021 07:06
Has thanked: 117 times
Been thanked: 405 times
Kontaktdaten:

CMP/BCx

Beitrag von Olix »

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

Benutzeravatar
Olix
Beiträge: 987
Registriert: 17.08.2021 07:06
Has thanked: 117 times
Been thanked: 405 times
Kontaktdaten:

Re: CMP/BCx

Beitrag von Olix »

... 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 ...
BRanch.jpg
BRanch.jpg (92.95 KiB) 827 mal betrachtet

Online
Benutzeravatar
Kveldulfur
Beiträge: 624
Registriert: 17.08.2021 02:32
Has thanked: 237 times
Been thanked: 163 times
Kontaktdaten:

Re: CMP/BCx

Beitrag von Kveldulfur »

Schleife von 5 bis 1

Code: Alles auswählen

		LDX #5
Loop:		NOP
		NOP
		DEX
		BNE Loop
Schleife von 5 bis 0

Code: Alles auswählen

		LDX #5
Loop:		NOP
		NOP
		DEX
		BPL Loop
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.

Benutzeravatar
Olix
Beiträge: 987
Registriert: 17.08.2021 07:06
Has thanked: 117 times
Been thanked: 405 times
Kontaktdaten:

Re: CMP/BCx

Beitrag von Olix »

Und entsprechend noch in die andere Richtung von 1 bis 5:

Code: Alles auswählen

          LDX #1
LOOP:     NOP
          NOP
          INX
          CPX #6
          BNE LOOP
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.

Benutzeravatar
Olix
Beiträge: 987
Registriert: 17.08.2021 07:06
Has thanked: 117 times
Been thanked: 405 times
Kontaktdaten:

Re: CMP/BCx

Beitrag von Olix »

... und noch eine Schleife von 0 bis 255:

Code: Alles auswählen

          LDX #0
LOOP:     NOP
          NOP
          INX
          BNE LOOP
Die Schleife wird beendet sobald der Wert nach der Inkrementierung wieder 0 ist

Benutzeravatar
Dr. Irata
Beiträge: 937
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 268 times
Kontaktdaten:

Re: CMP/BCx

Beitrag von Dr. Irata »

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:

Code: Alles auswählen

		#if .byte var1<#10
		.... hier steht der Code ....
		#end
wird zu:

Code: Alles auswählen

		lda var1
		cmp #10
		bcs weiter
		.... hier steht der Code ....
weiter		
und dann in MADS:

Code: Alles auswählen

		#if .byte var1>=#120 .and var4<#240
		.... hier steht der Code ....
		#end
wird zu:

Code: Alles auswählen

		lda var1
		cmp #120
		bcc weiter
		cmp #240
		bcs weiter
		.... hier steht der Code ....
		
weiter				
Zur besseren Übersicht habe ich hier extra eine Variable (var1) mit Werten verglichen, man kann natürlich auch statt der Werte weitere Variablen einsetzen.

Benutzeravatar
LarsImNetz
Beiträge: 152
Registriert: 24.08.2021 18:27
Has thanked: 109 times
Been thanked: 81 times
Kontaktdaten:

Re: CMP/BCx

Beitrag von LarsImNetz »

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:

Code: Alles auswählen

 lda var1
 beq sprung_wenn_var1_ist_0
in 16 bit

Code: Alles auswählen

 lda var1
 ora var1+1     ; hier werden beide Teile der Zahl zusammen geodert.
 beq sprung_wenn_var1_ist_0
Lars

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast