Hallo, für ein Projekt muss ich ein kurzes Stück Code beisteuern, dass testet, ob alle Register r0-r31 eines ATmega16 mit 0 initialisiert sind, und sonst einen Sprung macht (z.B. Neustart). Ich habe es primitiv hiermit versucht: [c] asm volatile( \ [...] "cpi r16, 0x00 \n" \ "brne 0x00 \n" \ [...] ); [\c] Dieses Vorgehen klappt aber nur für die Register r16-r31, sonst erscheint der Fehler: "Error: register number above 15 required" Also dachte ich mir, ich mache einen Workaround, indem ich Register miteinander vergleiche: [c] asm volatile( \ [...] "cpi r31, 0x00 \n" \ "brne 0x00 \n" \ "cp r0, r31 \n" \ "brne 0x00 \n" \ [...] ); [\c] Dann sagt mir der Compiler aber: "Error: operand out of range" Ich habe wohl ein Brett vor'm Kopf, weil eigentlich müsste das doch ganz einfach gehen... THX Bernd (P.S.: Bitte nicht fragen/schimpfen, warum ich die Funktionalität so und nicht anders brauche, das habe ich mir nicht ausgesucht ;-))
z.B. nach erfolgreicher Prüfung der r16 bis r31 die unteren prüfen, in dem der Inhalt des jeweils zu Prüfenden in r16 umkopiert und dieses dann geprüft wird?
nope, leider wieder ein Fehler
1 | asm volatile ( \ |
2 | [...]
|
3 | "mov r31, r0 \n" \ |
4 | "cpi r31, 0x00 \n" \ |
5 | "brne 0x00 \n" \ |
6 | [...]
|
7 | );
|
"Error: operand out of range: -67" Danke für den Vorschlag
> brne 0x00 Überprüfe diese Anweisungen. Du willst an ein Label springen, welches an Adresse 0 liegt? Achte darauf, dass der Sprung innerhalb von -64 bis +63 Adressen ab dem aktuellen Programmzähler PC liegen muss. > "Error: operand out of range: -67" Dein Label an 0x00 ist im Moment anscheinend -67 Adressen vorher, d.h. 3 Adressen zuw weit weg.
THX! Das hatte ich übersehen. Ich habe jetzt folgende Lösung:
1 | asm volatile( \ |
2 | [...]
|
3 | "cpi r31, 0x00 \n" \ |
4 | "brne 0x00 \n" \ |
5 | "cpse r0, r31 \n" \ |
6 | "jmp 0x00 \n" \ |
7 | [...]
|
8 | );
|
Danke für die Hilfe!
brne 0x00 ist ein nutzloser Befehl. Er bedeutet: springe 0 Schritte nach vorn.
Hallo, ich habe dasselbe Problem. ich weiß aber nicht was bei mir los ist. kann Jemand mir helfen? Danke. Christian ERROR: register number above 15 required
1 | void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0) |
2 | {
|
3 | asm volatile("push r1" "\n\t" |
4 | "eor r18, r18 ;r18<-0" "\n\t" |
5 | "eor r19, r19 ;r19<-0" "\n\t" |
6 | "1:" "\n\t" |
7 | "out 0x08, r19" "\n\t" |
8 | "add r18, %0 ;1 cycle" "\n\t" |
9 | "adc r19, %1 ;1 cycle" "\n\t" |
10 | "adc %A3, %2 ;1 cycle" "\n\t" |
11 | "lpm ;3 cycles" "\n\t" |
12 | "out 0x02, __tmp_reg__ ;1 cycle" "\n\t" |
13 | "ldi r1, 0xff" "\n\t" |
14 | "out 0x08, r1 ; cs=1;rw=1; cs und rw in PORTC" "\n\t" |
15 | "pop r1" "\n\t" |
16 | ";sbis %5, 2 ;1 cycle if no skip" "\n\t" |
17 | "rjmp 1b ;2 cycles. Total 10 cycles" "\n\t" |
18 | :
|
19 | :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTA)), "I" (_SFR_IO_ADDR(SPCR)) |
20 | :"r18", "r19" |
21 | );
|
22 | }
|
> "ldi r1, 0xff" "\n\t"
ldi geht nicht mit r1.
Registernumber > 15
Das ist halt ein Risc Prozessor, da kann man nicht jedes Register für jede Funktion nutzen.
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.