Hey, ich bin grad schon wieder zum X-ten mal über den Befehl CPSE gestolpert. Ich hab mich riesig gefreut, was der alles auf einmal macht - um dann festzustellen, dass er für mich genau falsch rum ist. CPSE vergleicht zwei Register und überspringt den nächsten Befehl, wenn beide Register gleich sind. ich hätt schon oft ein CPSN oder noch besser: CPISN gebraucht. Also dass der nächste Befehl übersprungen wird, wenn die beiden Register NICHT gleich sind bzw. wenn ein Register und eine Konstante ungleich sind. Auch ein TSTSN würd ich oft hernehmen, also Befehl überspringen, wenn ein Register nicht 0 ist. Tragisch ist es natürlich nicht, dann muss ich eben 2 Befehle benutzen. Aber irgendwie wundert mich, dass Atmel genau den Befehl implementiert hat, der zumindest meiner Meinung nach der nutzloseste der genannten Varianten ist. Nimmt den von euch wer her und ich bin einfach noch nicht drauf gekommen, wie ich ihn richtig einsetz? Grüße, Alex
Der ist möglicherweise speziell für Funktionen wie strncpy/memchr... vorgesehen, die sowohl einen Zähler als auch einen Wert als Abbruchbedingung haben. Läuft dann raus auf sowas wie: l1: ld r1,x+ dec r2 cpse r1,r0 brne l1
Hallo, Alexander v. Grafenstein schrieb: > Hey, > > ich bin grad schon wieder zum X-ten mal über den Befehl CPSE gestolpert. > Ich hab mich riesig gefreut, was der alles auf einmal macht - um dann > festzustellen, dass er für mich genau falsch rum ist. > > CPSE vergleicht zwei Register und überspringt den nächsten Befehl, wenn > beide Register gleich sind. komisch, geht mir genauso, ich ignoriere ihn seitdem eigentlich meist... ;-) In bestimmten Schleifen macht er Sinn, wenn der übersprungene Befehl dann der rjmp zum Schleifenanfang ist. ldi r16, 0x55 ; als Vergleichswert loop: in r17,PORTB cpse r16,r17 rjmp loop ... loop: in r17,PORTB cpi r17,0x55 brne loop macht hier letztlich das Gleiche und spart ein Register. Man müßte also wohl gezihlt nach Anwendungen suchen??? Gruß aus Berlin Michael
ah ok, dass könnte gut sein. Ich ärger mich einfach nur jedes mal, wenn ich ihn seh :) Danke für die Hinweise ! /edit: ui, geht das hier schnell
Hallo, A. K. schrieb: > Der ist möglicherweise speziell für Funktionen wie strncpy/memchr... > vorgesehen, die sowohl einen Zähler als auch einen Wert als > Abbruchbedingung haben. Läuft dann raus auf sowas wie: > > l1: ld r1,x+ > dec r2 > cpse r1,r0 > brne l1 Hmmm... l1: ld r1,x+ dec r2 cp r1,r0 brne l1 macht das Gleiche, mir iat aber gerade der entscheidende Unterschied aufgefallen: CPSE verändert die Flags nicht! da muß ich mal auf eine Anwendung achten... Gruß aus Berlin Michael
Stimmt. Jetzt hab ich auch das Beispiel von A.K. richtig verstanden. Da wird das voll ausgenutzt. Hatte gedacht, da fehlt doch noch was, wenn auf zwei Abbruch-Kriterien überprüft werden soll. D'oh :) Sowas kann man dann wirklich seehr elegant machen.
>> l1: ld r1,x+ >> dec r2 >> cpse r1,r0 >> brne l1 >Hmmm... > l1: ld r1,x+ > dec r2 > cp r1,r0 > brne l1 >macht das Gleiche, Nein macht es nicht. Das BRNE oben bezieht sich auf die Flags die beim DEC R2 verändert wurden. In deinem Beispiel bezieht sich BRNE auf den Vergleich CP r1,r0 wodurch dann auch das DEC R2 nicht ausgewertet wird und somit sinnfällig wäre. Gruß Hagen
Hallo, Hagen schrieb: >>> l1: ld r1,x+ >>> dec r2 >>> cpse r1,r0 >>> brne l1 > >>Hmmm... > >> l1: ld r1,x+ >> dec r2 >> cp r1,r0 >> brne l1 > >>macht das Gleiche, > > Nein macht es nicht. Das BRNE oben bezieht sich auf die Flags die beim > DEC R2 verändert wurden. In deinem Beispiel bezieht sich BRNE auf den > Vergleich CP r1,r0 wodurch dann auch das DEC R2 nicht ausgewertet wird > und somit sinnfällig wäre. > > Gruß Hagen ja, war mir inzwischen aufgefallen, man muß sich eben die Befehle auch nach Jahren asm noch genau anschauen... :-) Gruß aus Berlin Michael
Ich verwende CPSE sehr gerne. Für den inversen Fall von CPSE verwende ich zwei CPSE hintereinander . Weiterhin habe ich meist ein Register auf Null reserviert. Schleifen werden dadurch einfacher.
1 | .def leer =r2 |
2 | .def work =r16 |
3 | clr leer |
4 | ... |
5 | cpse work,leer |
6 | cpse leer,leer |
7 | JMP xxx |
Vorteile: FLAG neutral Interruptfest unbegrenzte Sprungmöglichkeiten (im Gegensatz zu Branch) Festgelegte und konstante Taktanzahl Für mehrere Vergleiche kann man auch CPSE Kaskaden verwenden, jedoch wird dass schnell unübersichtlich und sollte vermieden werden. cu Hauke
der CodeVision-compiler liebt den cpse.... ATmega88 instruction use summary: adc : 12 add : 13 adiw : 10 and : 1 andi : 3 asr : 0 bclr : 0 bld : 0 brbc : 0 brbs : 0 brcc : 2 brcs : 4 break : 0 breq : 11 brge : 0 brhc : 0 brhs : 0 brid : 0 brie : 0 brlo : 8 brlt : 0 brmi : 0 brne : 14 brpl : 0 brsh : 1 brtc : 0 brts : 0 brvc : 0 brvs : 0 bset : 0 bst : 0 cbi : 5 cbr : 1 clc : 0 clh : 0 cli : 4 cln : 0 clr : 22 cls : 0 clt : 0 clv : 0 clz : 0 com : 0 cp : 2 cpc : 5 cpi : 21 cpse : 0 dec : 4 eor : 0 fmul : 0 fmuls : 0 fmulsu: 0 icall : 0 ijmp : 0 in : 10 inc : 0 ld : 28 ldd : 14 ldi : 156 lds : 29 lpm : 8 lsl : 2 lsr : 0 mov : 19 movw : 19 mul : 12 muls : 0 mulsu : 0 neg : 0 nop : 0 or : 0 ori : 3 out : 41 pop : 5 push : 5 rcall : 50 ret : 26 reti : 6 rjmp : 50 rol : 10 ror : 0 sbc : 4 sbci : 8 sbi : 12 sbic : 3 sbis : 5 sbiw : 8 sbr : 2 sbrc : 2 sbrs : 0 sec : 0 seh : 0 sei : 2 sen : 0 ser : 0 ses : 0 set : 0 sev : 0 sez : 0 sleep : 0 spm : 0 st : 27 std : 8 sts : 58 sub : 2 subi : 14 swap : 0 tst : 2 Man könnte mal suchen, wofür eingesetzt.
> cpse : 0
Wenn ich die Tabelle richtig lese, wird cpse genau 0 mal eingesetzt.
Und aus einem andern Projekt, auch Fehlanzeige. ATmega8 instruction use summary: adc : 23 add : 19 adiw : 37 and : 2 andi : 6 asr : 0 bclr : 0 bld : 33 brbc : 0 brbs : 0 brcc : 5 brcs : 4 break : 0 breq : 88 brge : 3 brhc : 0 brhs : 0 brid : 0 brie : 0 brlo : 34 brlt : 2 brmi : 9 brne : 98 brpl : 7 brsh : 14 brtc : 1 brts : 1 brvc : 4 brvs : 4 bset : 0 bst : 3 cbi : 5 cbr : 0 clc : 3 clh : 0 cli : 5 cln : 0 clr : 52 cls : 0 clt : 24 clv : 0 clz : 2 com : 8 cp : 19 cpc : 13 cpi : 137 cpse : 0 dec : 10 eor : 12 fmul : 0 fmuls : 0 fmulsu: 0 icall : 0 ijmp : 0 in : 10 inc : 6 ld : 67 ldd : 96 ldi : 373 lds : 45 lpm : 16 lsl : 16 lsr : 2 mov : 106 movw : 65 mul : 15 muls : 0 mulsu : 0 neg : 4 nop : 0 or : 8 ori : 7 out : 50 pop : 33 push : 33 rcall : 635 ret : 151 reti : 4 rjmp : 283 rol : 31 ror : 12 sbc : 9 sbci : 32 sbi : 9 sbic : 3 sbis : 2 sbiw : 31 sbr : 1 sbrc : 23 sbrs : 46 sec : 4 seh : 0 sei : 3 sen : 0 ser : 8 ses : 0 set : 20 sev : 0 sez : 1 sleep : 0 spm : 0 st : 136 std : 31 sts : 32 sub : 6 subi : 58 swap : 0 tst : 36 wdr : 1 Instructions used: 78 out of 109 (71.6%)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.