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
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.
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