Hi, ich hab folgendes Programm geschrieben: Dabei hab ich folgendes Problem - wenn ich an der Stelle sbic PINC,0 in das "Unterprogramm" Zaehl springe, dann hüpft ds Programm nach dem Ret-Befehl nicht zurück wo es hinsoll, es soll eigentlich der nächste Befehl auch abgefragt werden - sbic PINC,1 ..., aber es springt zum Anfang des Programms an ldi r20,0x00 zurück und startet von ganz vorne, dass es aber nicht soll. wo liegt der Fehler? .include "m8def.inc" ; Setze Zaehler r20 auf Null ldi r20, 0x00 ldi r22, 0x00 ldi r24, 0x00 main: ; Setze Bit 012 PortC als Schalter ldi r16, 0x00 out DDRC, r16 loop: ;in r16, PINC sbic PINC,0 ijmp Zaehl sbic PINC,1 inc r22 sbic PINC,2 inc r24 rjmp loop Zaehl: inc r20 ret
Du hast den Stackpointer nicht initialisiert. Dein Programm weiß nicht wo es hinspringen soll
ret ist der Befehl mit dem man aus einem Unterprogramm zurückspringt. Du hast aber keinen Unterprogrammaufruf. Dieser wäre ein rcall oder call. Ein jmp ist aber kein call. Er legt die Rücksprungadresse nicht auf den Stack.
Hi
>wo liegt der Fehler?
Ein Unterprogramm ruft man mit rcall/call auf. Dann klappt es auch mit
dem ret. Das founktioniert aber nur, wenn der Stackpointer initialisiert
ist.
MfG Spess
Anfaenger ASM schrieb: > ijmp Zaehl Falscher Befehl. Ein Jump verzweigt einfach nur, aber speichert keine Rücksprunginformation. Dazu musst du einen Call-Befehl verwenden. mfg.
Thomas Eckmann schrieb: > Falscher Befehl. Ein Jump verzweigt einfach nur, aber speichert keine > Rücksprunginformation. Dazu musst du einen Call-Befehl verwenden. Schade, ijmp durch rcall ersetzen, dass klappt leider nicht. da kommt das gleiche bei raus.
Hi >Schade, ijmp durch rcall ersetzen, dass klappt leider nicht. da kommt >das gleiche bei raus. Stackpointer initialisieren. MfG Spess
Rolf Magnus schrieb: > Auch wenn du wie vorgeschlagen den Stackpointer initialisierst? cool, jetzt hat es gefunktioniert.Vielen Dank mit dem Stackpointerhinweis. Eine Frage hab ich noch - sollte man sich immer angewoehnen, die Zeilen push temp in temp, SREG Quelltext Unterprogramm out SREG, temp pop temp ret reinzuschreiben,um da was zu sichern,oder ist das nicht nötig? Auf einer der Seiten im Tutorial wurde das so geschrieben. .include "m8def.inc" ; Setze Zaehler r20 auf Null .def temp = r16 ldi temp, HIGH(RAMEND) ; HIGH-Byte der obersten RAM-Adresse out SPH, temp ldi temp, LOW(RAMEND) ; LOW-Byte der obersten RAM-Adresse out SPL, temp ldi r20, 0x00 ldi r22, 0x00 ldi r24, 0x00 main: ; Setze Bit 012 PortC als Schalter ldi r16, 0b1111000 out DDRC, r16 loop: ;in r16, PINC sbic PINC,0 rcall Zaehl sbic PINC,1 inc r22 sbic PINC,2 inc r24 rjmp loop Zaehl: push temp in temp, SREG inc r20 out SREG, temp pop temp ret
Hi >...reinzuschreiben,um da was zu sichern,oder ist das nicht nötig? Auf einer >der Seiten im Tutorial wurde das so geschrieben. Das ist nur bei Interruptroutinen notwendig. Bei Unterprogrammen ist es notwendig, Register, die nicht verändert werden dürfen, am Anfang mit 'push rxy' zu sichern und am Ende mit 'pop rxy' wieder zu rekonstruieren. MfG Spess
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.