Geschätztes Forum, folgenden Effekt kann ich mir nicht erklären, so funktioniert es: ldi ZL, LOW (SPRUNGMARKE) ldi ZH, HIGH(SPRUNGMARKE) add ZL,R16 adc ZH,NULL IJMP ; SPRUNG (Zeiger nach Z) SPRUNGMARKE: rjmp ROUTINE_A rjmp ROUTINE_B rjmp ROUTINE_C rjmp ROUTINE_D rjmp ROUTINE_E Aber so, nur komische Effekte, aber keine Fehlermeldung im AVR-Studio4: ldi ZL, LOW (SPRUNGMARKE) ldi ZH, HIGH(SPRUNGMARKE) add ZL,R16 adc ZH,NULL IJMP ; SPRUNG (Zeiger nach Z) SPRUNGMARKE: jmp ROUTINE_A jmp ROUTINE_B jmp ROUTINE_C jmp ROUTINE_D jmp ROUTINE_E Danke Bernhard Nachtrag: betrifft den ATmega1284P
die Reichweite von rjmp begrenzt. Es kommt vermutlich darauf an, wo denn ROUTINE_A im Speicher liegt. ist sie Relativ weit weg, oder relativ am Anfang?
jmp belegt zwei Worte, das add/adc R16 muss also zweimal erfolgen.
Ich danke Euch !
>jmp belegt zwei Worte
So funktioniert es:
ldi ZL, LOW (SPRUNGMARKE)
ldi ZH, HIGH(SPRUNGMARKE)
LSL R16 ; mal 2 (nur bei R16=0...127)
add ZL,R16
adc ZH,NULL
IJMP ; SPRUNG (Zeiger nach Z)
SPRUNGMARKE:
...
Bernhard
Bernhard S. schrieb: > So funktioniert es: > > ldi ZL, LOW (SPRUNGMARKE) > ldi ZH, HIGH(SPRUNGMARKE) > > LSL R16 ; mal 2 (nur bei R16=0...127) > > add ZL,R16 > adc ZH,NULL > IJMP ; SPRUNG (Zeiger nach Z) > SPRUNGMARKE: Und so funktioniert es auch dann, wenn in R16 Werte zwischen 128 und 255 stehen: ldi ZL, LOW (SPRUNGMARKE) ldi ZH, HIGH(SPRUNGMARKE) lsl R16 adc ZH,NULL add ZL,R16 adc ZH,NULL ijmp SPRUNGMARKE: jmp ROUTINE_A ... Kostet allerdings auch einen Takt mehr als deine Variante. Oder, noch besser, dauert nämlich genauso nur einen Takt mehr, spart aber dafür auch noch die Hälfte des Flashspace für die Sprungtabelle: ldi ZL, LOW (SPRUNGMARKE<<1) ldi ZH, HIGH(SPRUNGMARKE<<1) lpm R16,Z+ lpm ZH,Z mov ZL,R16 ijmp SPRUNGMARKE: .DW ROUTINE_A ...
Ich vergaß: sowie elpm. Und dann dauert es erstens länger und wird zweitens nicht so ganz einfach.
Okay, bei der Ausführungszeit lagen wir beide falsch, es fällt ja das jmp weg. Trotzdem würde ich die erste Lösung mit zweifachem Addieren vorziehen.
der alte Hanns schrieb: > Trotzdem würde ich die erste Lösung mit zweifachem Addieren vorziehen. Ich auch. Die zweite war namlich schlicht und einfach völliger Blödsinn. Da fehlt der entscheidende Schritt, der Sprungverteiler. Deswegen war das wohl auch so überraschend schnell... Aber für Routine_A hätte es immerhin tatsächlich funktioniert. ;o) Einfach vergessen diesen Quatsch. OMG, heute ist wohl echt nicht mein Tag.
Zwar verstehe ich nicht ganz, was Sie jetzt meinen, aber egal, mein Tag war's heute nämlich auch nicht. Ich steig wieder aufs Turmdach rauf.
Ah - jetzt - ja: die adds fehlen. Bleibt also nur die Platzersparnis, und die ist bei Assembler auf einem 1284 wohl eher nachrangig. (Wie schon erwähnt, dauert's bei mir heute besonders lange) Schönen Abend noch.
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.