Forum: Mikrocontroller und Digitale Elektronik Vergleichen?


von Freak5 (Gast)


Lesenswert?

Ich steige beim Atmel nicht durch die Befehle des Vergleichens!

Ich habe zwar schon Befehle wie:
BREQ
BRLT
BRLO
gefunden, aber ich habe noch kein
"Springe wenn wahr" gesehen.

Wo ist dieser Sprungbefehl?
Bei rjmp macht man doch das gleiche wie bei jmp, oder?

OH jetzt habe ich es.
Da ist auch ein CP Befehl.

Heißt dass, dass man einen bedingten Sprung jetzt so macht

CP R17,R18
BRLO MeinLabel

???????????

von Michael (ein anderer) (Gast)


Lesenswert?

Ja, so funktioniert das: Erst vergleichen, dann bedingt springen.

von Freak5 (Gast)


Lesenswert?

Danke.
Jetzt verstehe ich die Tabelle auch richtig.

von A.K. (Gast)


Lesenswert?

Quizfrage für Fortgeschrittene: Wozu ist der Befehl CPSE gut?

von Freak5 (Gast)


Lesenswert?

Naja in der Beschreibung steht, dass man damit vergleicht und
anscheinend gleich den nächsten Befehl überspringt wenn es gleich ist.

Damit kann man sicher was machen, z.B.: kann man irgendwohin springenl,
wenn es gleich ist und irgendwoanders hin, wenn es kleiner ist.
Das kombiniert wäre ...
Naja das bekommt man mit cmp auch hin.

Der Befehl spart vielleich eine Zeile Programmierarbeit :-)

von A.K. (Gast)


Lesenswert?

Dieser Befehl ist so speziell, dass es ganz bestimmte wichtige
Anwendungen dafür geben muss, ansonsten gäbe es ich nicht. Aber
welche?

Bislang gefunden: memchr/strnlen und dergleichen:
l1: ld   r1,x+
    dec  r2
    cpse r1,r0
    brne l1

Ohne CPSE
l2: ld   r1,x+
    cp   r1,r0
    breq l3
    dec  r2
    brne l2
l3:
ist es auch nur 1 Takt langsamer.

von Bri (Gast)


Lesenswert?

Hallo Leute, schön zu sehen, daß ich nicht der einzige bin, dem der cpse
Befehl sehr sinnfrei vorkommt. Ich habe dutzende Fälle, wo ich genau das
Gegenteil von dem cpse bräuchte, also cpsne (z.B. für switch case
Blöcke). Aber ich hatte bisher nur einen Fall, wo ich den cpse
einsetzen konnte:

; RAM löschen
        clr     r16
        ldi     r17,HIGH(RAMEND)
        ldi     r18,LOW(RAMEND)
        ldi     XH,HIGH(SRAM_START)
        ldi     XL,LOW(SRAM_START)
main_clear_ram:
        st      X+,r16
        cpse    r17,XH
        rjmp    main_clear_ram
        cpse    r18,XL
        rjmp    main_clear_ram

von Andi (Gast)


Lesenswert?

Und ohne CPSE wäre das dann noch ein bißchen kürzer:

; RAM löschen
        clr     r16
        ldi     XH,HIGH(SRAM_START)
        ldi     XL,LOW(SRAM_START)
main_clear_ram:
        st      X+,r16
        cpi     XL,LOW(RAMEND)
        brne    main_clear_ram
        cpi     XH,HIGH(RAMEND)
        brne    main_clear_ram

Kommt halt wirklich auf den Anwendungsfall an und der ist bei CPSE sehr
selten.

MfG
Andi

von ...HanneS... (Gast)


Lesenswert?

CPSE hat aber den Vorteil, dass die Flags nicht beeinflusst werden.

CPSNE hätt ich mir auch schon gewünscht... ;-)

...

von Bri (Gast)


Lesenswert?

@Andi

Du hast recht! Und ich würde auch zwei Register weniger brauchen. Ich
sollte nicht mehr nach Mitternacht programmieren. Ist ja peinlich ;-)

von Carsten (Gast)


Lesenswert?

gibt es sowas wie CPSE auch für ungleich ? vielleicht CPSNE ?
Alternativ, gibt es vielleicht ein BREQ mit Rücksprungfunktion (wie
rcall)
Ich muss in eine Subroutine springen, wenn zwei Register gleich sind.

von Andi (Gast)


Lesenswert?

cp r0,r1
 brne NoEqual
 rcall Equal
NoEqual:
 .....

MfG
Andi

von ...HanneS... (Gast)


Lesenswert?

:)

...

von Carsten (Gast)


Lesenswert?

...nicht schön aber selten...
Schade, dachte ich könnte mir das Label sparen.

Danke

von Marcel (Gast)


Lesenswert?

Label sparen?

Das ist wirklich, woran man nicht sparen braucht.. Denn Label sind und
bleiben halt nur Label: Namen für Adressen.

Und wenn du wirklich so faul bist da ein Label hin zu schreiben, dann
wirst du wahrscheinlich auch deine codes nicht kommentieren.

Viel spaß in einem halben Jahr, wenn du die wieder auskramst und wider
verwenden willst. (Oder achtest du nicht auf portabilität usw?)

von Carsten (Gast)


Lesenswert?

Tut mir leid, dass ich so'n faules Arschloch bin, dass obendrein auch
noch die Frechheit besitzt zu fragen!!!!
Solche unqualifizierten Bemerkungen kannst Du Dir sparen !

von Marcel (Gast)


Lesenswert?

hey mann was geht denn mit dir ab?!! musst dich doch nicht gleich
angegriffen fühlen...

von Carsten (Gast)


Lesenswert?

Ich weiss nicht ob Du's schon mal gehört hast aber auf einen 2313 einen
512MB Chip zu stecken geht nicht.
Da könnte man vielleicht von vorn herein versuchen den Code knapp zu
halten.
Das hat mit Faulheit nichts zu tun.
Keine Sorge, meine Kommentare sind schon ausreichend. Die werden M.E.
auch nicht in den Controller geschrieben.
So ein Label denke ich aber schon, zumal dann noch mindestens ein
Befehl dazu kommt.

von ...HanneS... (Gast)


Lesenswert?

Labels kosten keinen Speicher, sie sind nur Namen für die Adresse, an
der das Label steht. Die Adresse ist also auch ohne Label vorhanden.

...

von mmerten (Gast)


Lesenswert?

viele Labels machen aber die Symbol-Tabelle oder xref etwas
unübersichtlich.
Es geht alternativ aber auch so:

cp r0,r1
 brne PC + 2
 rcall LABEL_EQ
 ....

--------------------------

LABEL_EQ:
 ret

von Carsten (Gast)


Lesenswert?

Das macht Sinn.
Danke, das ist genau das, was ich gesucht habe.

von ---- (Gast)


Lesenswert?

> Es geht alternativ aber auch so:
> cp r0,r1
> brne PC + 2
> rcall LABEL_EQ
> ....
Ja und zwar solange, bis das rcall <label> durch ein anderen 1- oder
3-Bytebefehl ausgetauscht wird... :-(
Die Verwendung dieses "Tricks" ist eher fragwürdig.


> Oder achtest du nicht auf portabilität usw?
Portabilität? Ich dachte wir sprechen hier von Assembler? :-) Da
gibt's sowas nicht...


> nicht in den Controller geschrieben [...] So ein Label denke ich
> aber schon, zumal dann noch mindestens ein Befehl dazu kommt.
Labels und Befehle haben keinen Zusammenhang. Und daß durch Labels kein
Speicherverbrauch resultiert, hat Hannes ja schon geschrieben.

----, (QuadDash).

von mmerten (Gast)


Lesenswert?

@-----
Wo es beim AVR 1 ... 3 Byte Befehle gibt, ist mit schleierhaft :-)
Da gibt`s nur 1 oder 2 word Befehle und der nachfolgende zu
überspringende Befehl ist ja bekannt. als kann ich PC + 2 oder PC + 3
kodieren.

von Clemens (Gast)


Lesenswert?

Hallo,

wo wir grad beim Thema Label sind:

Dass Label keinen Speicher brauchen ist schon klar, aber dennoch gehen
einem ja irgendwann die Namen aus.
Mein Problem jetzt ganz konkret: Angenommen in mache soetwas wie eine
Select-Anweisung. Da kommt als Abfrage immer soetwas wie

ProzedurName_3:
    cpi rArg, 0x02
    brne ProzedurName_4
;         rArg == 0x02, also irgendwas tun
ProzedurName_4:
;   nächste Abfrage

Wenn man jetzt nochmal kurz eine weitere Abfrage vor diese Abfrage
schreiben will, ist man schon mit Problemen überhäuft: Welches Label?
Oder doch lieber alle folgenden Label um eine Nummer am Ende erhöhen?

Hier würde ich mir Wünschen etwas wie das folgende benutzen zu können

@@:
    cpi rArg, 0x02
    brne @F
;         rArg == 0x02, also irgendwas tun
@@:
;   nächste Abfrage

und so weiter. Dabei hiesse z.B. @F nächstes auftretendes Label mit
Namen "@@" und @B das vorige Label mit Namen "@@". Eine Erweiterung
zu @BB und @FF wäre auch noch denkbar für die übernächsten und
vor-vorigen... Dann könnte man einfach eine weitere Anweisung einfügen
und hätte gleich alle Referenzerneuerungen vom Assembler gelöst.

Gibt es das schon oder ist es erst in Planung?

PS: Ich kenne das aus dem MacroAssembler von Microsoft für Intel
x86-Architekturen... eine sehr praktische Sache.

Schöne Grüße, Clemens

von ---- (Gast)


Lesenswert?

> @-----
> Wo es beim AVR 1 ... 3 Byte Befehle gibt, ist mit schleierhaft :-)
1- oder 3-Byte Befehle gibts da wo es auch 5-strichige _Quad_dashs
gibt. ;-)
Ok, auch wenns diese Längen nicht gibt, es wurde ja klar, was ich damit
gemeint habe.

----, (QuadDash).

von Andi (Gast)


Lesenswert?

Oder wie wärs mit nen Macro?

.macro RCallEQ   ;Relative Call to @0 if @1 <> @2
  cp @1,@2
  brne continue
  rcall @0
continue:
.endm

Dieses kleine Macro kann man sich in seine eigene Macro-Dateien
einfügen welche man natürlich im Hauptprogramm am Anfang includen
sollte.

Aufruf, bzw. Einbindung ist dann wie folgt:

  RCallEQ Subroutine, r16, r17

Falls das jemand ab Mega16 und größer verwenden will und ein RCALL
nicht ausreicht macht man noch folgendes Macro:

.macro CallEQ   ;Call to @0 if @1 <> @2
  cp @1,@2
  brne continue
  call @0
continue:
.endm

Aufruf dann z. B. mit

  CallEQ Subroutine, r16, r17

Für andere Vergleiche wie CC (Carry Clear), CS (Carry Set) usw. macht
man sich eine Kopie und bennent es z. B. in RCallCS.
Man muß das brne dann in brcc ändern, eben das Gegenteil.

Ist zwar auch nicht des Weisen letzter Schluss aber Macros schaffen
Übersicht.

MfG
Andi

von Andi (Gast)


Lesenswert?

...#%&$%'$&'%&
Sollte heißen "Relative Call to @0 if @1 = @2" und "Call to @0 if @1
= @2".

MfG
Andi

von Marcel (Gast)


Lesenswert?

@dotdash:
kaum portabilität (das betrifft auch die portierung von einem gerät auf
ein anderes - schlimmer noch die portierung auf einen anderen
controller-typ), aber wiederverwendbarkeit (man achte auf das usw in
meinem ersten Kommentar)!
oder erfindest du das rad immer wieder neu?


@andi
dann solltest du aber auch die labels neu machen (durchnummerieren oder
so) sonst hast du ganz schnell viele "continue:"s in deinem asm code

von Andi (Gast)


Lesenswert?

So was mußte ja wieder kommen!
Du kennst den Macro-Assembler von AVR-Studio noch nicht.
Jedes Macro, und wenn es 1000 mal im Hauptprogramm mit dem selben
"continue" aufgerufen wird, ist ein Teil für sich.
In alten Versionen des AVR-Studios ging das noch nicht, da mußte man
sich mit "PC+2" etc. rumplagen.
Jetzt handelt das AVR-Studio. Man kann sogar Macros in Macros aufrufen,
ausser sich selbst natürlich da AVR-Studio ab 7 oder 8 Rekursionen
schimpft.
Wozu sind denn Macros da, um sich das Leben (programmieren) zu
vereinfachen.

MfG
Andi

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.