Forum: Mikrocontroller und Digitale Elektronik Subroutine Return


von Izaords (Gast)


Lesenswert?

Hi

Ich habe ein Problem,  mein Programm soll nach dem letzten aufruf eines 
Unterprogramms in einer Endlosschlaufe enden.  Doch es springt an den 
Anfang des Programms und die Endlosschlaufe umfasst das ganze 
Programm!!!!

Mein Programm sieht etwa so aus wie unten eingefügt:

das letzte Unterprogramm (LCD_HEX) habe ich mit dem Befehl RET 
abgeschlossen doch er springt ans rjmp main ganz am Anfang!!!!

weiss jemand was ich da falsch gemacht habe????

Vielen Dank

Izoards



.include  "8515def.inc"


    rjmp    main


.include   "definition.inc"    ;
.include  "port_init.inc"      ;
.include  "lcd_ini.inc"      ;verschiedene Include- 
Dateien
.include  "delay.inc"      ;einbinden.
.include  "control_daten_send.inc"  ;
.include  "code wandler.inc"



main:        ldi    mpr, low (RAMEND)  ;Stackpointer
        out    spl, mpr    ;ans Ende des Internaly
        ldi    mpr, high (RAMEND)  ;SRAM Speichers
        out    sph, mpr    ;setzen

        rcall     port_init  ;Port initialisierung aufrufen
        rcall    lcd_ini  ;LCD intialisierung aufrufen

        ldi    daten, 0xFC
        rcall    LCD_HEX


loop:        rjmp    loop

von Jonas Diemer (Gast)


Lesenswert?

haste das mal im simulator durchgespielt?

vielleicht ein fehler im stack? voll?  vom programm modifiziert (liegt 
ja im ram)? oder die rücksprungadresse mit push überschrieben oder mit 
pop rausgeholt???


Jonas

von Izoards (Gast)


Lesenswert?

Oh ja, ich habe mit Push und Pop gearbeitet, und wenn ich diese weglasse 
funktioniert es auch!!! Vielen Dank!!!

Doch wieso kann ich ein Register nicht mit Push speichern, ohne dass es 
die rücksprungadresse überschreibt???
das müsste doch funktionieren¨!!!????

izoard

von Izoards (Gast)


Lesenswert?

Wow ja, es liegt am Pushen und Popen!!! ohne diese Befehle funktioniert 
es nämlich!!!
Aber ich müsste doch ein Register mit dem Befehl sichern können??? Was 
habe ich da falsch gemacht??? Vielleicht sieht das jemand??? Ich poste 
hier noch mein Unterprogramm lcd_hex!!!!


LCD_HEX:                  push    daten
    ldi    zaehler, 0x02
    swap    daten
HEX_loop:  andi    daten, 0x0F
    mov    mpr, daten
    subi    mpr, 0x0A
    brsh    highsm
    ori    daten, 0x30
    rjmp    go

highsm:    subi    daten, 0x09
    ori    daten, 0x40

go:    rcall    zeichen
    dec    zaehler
    pop    daten
    cpi    zaehler, 0x00
    brne    HEX_loop
;loop2:    rjmp    loop2
    ret

von Steffen (Gast)


Lesenswert?

Ich hab's jetzt nur mal überflogen, aber du PUSHst EINMAL ganz am Anfang 
(LCD_HEX). Du POPst aber unter umständen mehrfach, da der POP-Befehl in 
einer Schleife steht. Das geht so nicht. Das was auf den Stack geht, 
muss auch wieder runter. Und zwar genau so oft, wie es rauf ging.

von Izoards (Gast)


Lesenswert?

Ah ja suuper, vielen Dank...
Ich pushe nun das Register am Anfang einfach mehrmals!!! ist 
wahrscheinlich nicht die beste Lösung, oder schon????

von Jonas Diemer (Gast)


Lesenswert?

nee, nicht wirklich.

wenn du kein register mehr frei hast, also sachen für mehrfachen zugriff 
auf dem stack ablegen musst, dann solltest du es nach dem poppen gleich 
wieder pushen.

den stack musst du dir als stapel vorstellen. du hast immer nur zugriff 
auf das oberste element. auf dem stack werden auch rücksprungadressen 
gespeichert.

wieso popst du die daten eigentlich da unten vor dem sprung? wäre nach 
dem sprung nicht gescheiter?

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.