Forum: Mikrocontroller und Digitale Elektronik Problem mit ret-Befehl


von Anfaenger ASM (Gast)


Lesenswert?

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

von Daniel (Gast)


Lesenswert?

Du hast den Stackpointer nicht initialisiert. Dein Programm weiß nicht 
wo es hinspringen soll

von Karl H. (kbuchegg)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Thomas E. (thomase)


Lesenswert?

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.

von Thomas E. (thomase)


Lesenswert?

Ok, ich bin der langsamste.

von Anfaenger ASM (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

Hi

>Schade, ijmp durch rcall ersetzen, dass klappt leider nicht. da kommt
>das gleiche bei raus.

Stackpointer initialisieren.

MfG Spess

von Rolf Magnus (Gast)


Lesenswert?

Auch wenn du wie vorgeschlagen den Stackpointer initialisierst?

von Anfaenger ASM (Gast)


Lesenswert?

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

von spess53 (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.