Forum: Mikrocontroller und Digitale Elektronik Wie oft Unterprogramme im Unterprogramm aufrufen


von JSP (Gast)


Lesenswert?

Hey Leute,

ich hätt da mal ne Kurze Frage.

und zwar wio oft darf ich in einem Unterprogramm ein Unterprogramm 
aufrufen (rcall)? (ich meine in einen rcall ein rcall auffrufen)
Und wie groß dürfen die Unterprogramme sein?


Wenn ein Ineterrupt auftritt darf ich ja auch nicht  in dem 
Unterprogramm beliebig viele Befehle abarbeiten. Ist es bei den 
norlmalen Unterprogrammen auch so?

von Oliver (Gast)


Lesenswert?

???

Du darfst beliebig viele Unterprogramme schachteln, und die dürfen 
beiebig groß sein. Die Grenze ergibt sich durch den verfügbaren 
Speicher.

Du darfst prinzipiell auch Interrupt-Routienen beliebig lang machen, und 
aus denen beliebig tief geschachtelte Unterprogramme aufrufen. Das hat 
Einfluß auf die Abarbeitung anderer Programmteile, aber verboten ist das 
nicht.

Oliver

von Cyblord -. (cyblord)


Lesenswert?

Das geht solange bis dir der Stack überläuft.

von Udo S. (urschmitt)


Lesenswert?

Je nachdem, manche Pics hatten/haben? Hardwarestacks für 
Unterfunktionsaufrufe. Da war/ist es klar auf die Stacktiefe beschränkt.

von gugu (Gast)


Lesenswert?

Das lässt sich nicht pauschal sagen, das hängt auch davon ab, wie dein 
Compiler eingestellt ist und welche Parameter du beim Funktionsaufruf 
übergibst. Auch wäre es leichter abzuschätzen, wenn du dein Programm 
hier mit vorstellen würdest.

von spess53 (Gast)


Lesenswert?

Hi

>Das lässt sich nicht pauschal sagen, das hängt auch davon ab, wie dein
>Compiler eingestellt ist und welche Parameter du beim Funktionsaufruf
>übergibst.

Es geht um Assembler !

MfG Spess

von JSP (Gast)


Lesenswert?

ahhh ok, ich meine ich habs geschnallt.

Ich bin jetzt nur auf die Frage gekommen weil unsere Leherer damals 
gemeint hat das man die Interrupt Routine so kurz wie möglich halten 
sollte und man keine Unterprogramme aufrufen sollte.

von Cyblord -. (cyblord)


Lesenswert?

Udo Schmitt schrieb:
> Je nachdem, manche Pics hatten/haben? Hardwarestacks für
> Unterfunktionsaufrufe. Da war/ist es klar auf die Stacktiefe beschränkt.

Es ist eigentlich immer auf die Stacktiefe begrenzt. Einige kleine Tiny 
AVRs haben auch Hardwarestack. z.B. 3 Level. Aber auch ein Stack im Ram 
ist nunmal begrenzt.

von Udo S. (urschmitt)


Lesenswert?

cyblord ---- schrieb:
> Es ist eigentlich immer auf die Stacktiefe begrenzt. Einige kleine Tiny
> AVRs haben auch Hardwarestack. z.B. 3 Level. Aber auch ein Stack im Ram
> ist nunmal begrenzt.

Klar, aber 1. war das von Oliver und dir schon vorher gesagt und 2. ist 
das in der Regel deutlich mehr.

von Michael S. (rbs_phoenix)


Lesenswert?

JSP schrieb:
> Ich bin jetzt nur auf die Frage gekommen weil unsere Leherer damals
> gemeint hat das man die Interrupt Routine so kurz wie möglich halten
> sollte und man keine Unterprogramme aufrufen sollte.

Das ist meines Wissens so, weil wenn du ein Interrupt auf z.B. ein 
PortPin hast und sich dieser änder, kommst du damit in die 
Interrupt-Routine. Wenn das Programm dahinter zu lang ist, dann werden 
entweder spätere Interrupts nicht "gesehen", bzw ich denke eher, dass 
das Programm dann abgebrochen wird. Deswegen so kurz wie möglich, damit 
sowas nicht passiert. Mit den Unterprogrammen... Naja. Unterprogramme 
macht man ja eher wenn was größeres ist und öfter verwendet wird. Das 
ist dann wieder das gleiche wie ich oben meinte. Das liegt aber an der 
Abarbeitungslänge und nicht an der Unterfunktion. Wenn du eine 
Unterfunktion hast, die ein Bitmuster an einem Port ausgibt (was du 
woanders auch brauchst), dann kannst du die da auch ausführen.

von JSP (Gast)


Lesenswert?

ja stimmt, so hat er es auch glaub ich gemeint.

Danke an alle

von chick (Gast)


Lesenswert?

Das ist doch Wahnsinn:
>entweder spätere Interrupts nicht "gesehen", bzw ich denke eher, dass
>das Programm dann abgebrochen wird.


Denken ist ja gut, aber Programmabläufe, Interrupt-Behandlung, all das 
gehorcht Regeln, die man nachlesen und lernen kann.
Da ist dieses "denken" (=glauben, aber nicht wissen) fehl am Platz.

von Kein Name (Gast)


Lesenswert?

> das man die Interrupt Routine so kurz wie möglich halten sollte
> und man keine Unterprogramme aufrufen sollte

Nur in diesem einen Fall.

Mit Unterprogrammen wird dein Programm verständlicher, dafür etwas 
langsamer.

Du musst abwägen - Verständlich oder Schnell. Normalerweise ist es 
besser, du entscheidest dich für die Verständlichkeit. Nur in Interrupt 
Routinen musst du dich meistens für Geschwindigkeit entscheiden.

von bubu (Gast)


Lesenswert?

Ein call in assembler braucht 2 oder 4 byte Speicher, also kannst du 
deftigst verschachteln. Allerdings schlaegt jedes push auchnochmal mit 
16 oder 32 bit zu Buche, deswegen sollte man da wirklich nur wenige 
Register sichern. Es tut so ein call nicht weh, wenn man sein Programm 
dadurch vereinfachen kann!

von oldmax (Gast)


Lesenswert?

Hi
Also, ist ja schon viel geschrieben, aber so manches bedarf doch noch 
ein paar Worte.
Ein Unterprogramm, kein Interrupt !, braucht keine Push und POP Befehle. 
Hier ist der Aufruf ja an einer bekannten Stelle im Programm. Lediglich, 
wenn ich mir Werte sichern möchte, kann ich Push und POP benutzen.
Der Aufruf einer Sub-Routine speichert die dem Aufruf folgende 
Programmadresse im Stack, bevor der Programmcounter mit der Adresse des 
Unterprogramms gesetzt wird. Da eine Adresse in der Regel >255 ist, 
braucht es dafür mindestens 2 Byte auf dem Stack. Der Stack liegt, da er 
ja dauernd beschrieben wird im Bereich "DSEG", also da, wo auch 
Variablen liegen. Damit da nix überschrieben wird, werden die Variablen 
im unteren Adressbereich, also von unten nach oben eingetragen, der 
Stack aber om oberen Adressbereich und zwar entgegengesetzt von oben 
nach unten eingetragen. Wenn von einem Stack overflow die Rede ist, dann 
ist der Stack bereits bis in den Variablenbereich geraten. Der Befehl 
Push nutzt den Stack in gleicher Weise zum Retten von Registerwerten. 
RET und auch POP bauen den Stack wieder ab, bzw. geben den Speicher 
wieder frei.
Ein Interrupt ist ein Sonderfall eines Unterprogrammes. Während der 
Zeitpunkt des "CALL" oder auch "RCALL" bekannt ist und auch die Rückkehr 
aus dem Unterprogramm, ist es bei einem Interrupt eben nicht bekannt. 
Stellt euch vor, es ist gerade ein Vergleich erfolgt und bevor dieser 
inm nächsten Befehl bewertet werden kann, das geschieht ja aufgrund der 
Info im Statusregister, kommt eben ein Interrupt dazwischen. Auch hier 
wird eine Programmabfolge bearbeitet. Kehrt nun das Programm aus der 
Interrupt Service Routine zurück, kann das Statusregister völlig andere 
Ergebnisse beinhalten. Daher muß es genauso wie anderweitig benutzte 
Register vorher zwischengespeichert und vor Ende wiederhergestellt 
werden. Man muss sich also merken :
Alle Register, die in einer Interruptbearbeitung benutzt werden, müssen 
zwischengespeichert werden. Auch die, die in einem Unterprogramm sind, 
welches innerhalb der ISR aufgerufen wird.
Nun der Grund, warum ein Interrupt möglichst kurz sein soll:
Jeder Befehl benötigt zur Ausführung Zeit. Je nach Taktfrequenz mehr 
oder weniger. Sind in einer Interruptroutine viele Anweisungen, 
womöglich auch noch Schleifen programmiert, dauert es eben, bis das Ding 
durch ist. Ein Beispiel: der Timer Interrupt alle msek. Bei 1 MHz dauert 
ein Befehl
ca. 2 µSek. Würde ich also 500 Befehle in diesen Interrupt packen, wär 
für's Hauptprogramm keine Zeit mehr.
Mag sein, das nun schnell gesagt wird: "oooch, 500 Befehle, da komm ich 
nie hin." Na ja, da ist noch der UART, der IO, der ADC und und und...
Gruß oldmax

von Reinhard Kern (Gast)


Lesenswert?

Hallo,

noch zur Ergänzung:

wenn das Ereignis, das einen Interrupt ausgelöst hat, wieder eintritt, 
während die Interrupt-Routine noch läuft, ist das fast immer ein 
fehlerhafter Programmzustand. Dass z.B. ein Zählimpuls vergessen wird, 
ist dabei noch die harmloseste Folge. Verboten ist das erneute Auftreten 
des Interrupts aber nicht, schon garnicht in Assembler, da muss sich der 
Programmierer selber drum kümmern dass das nicht passiert, was bei der 
Embedded-Entwicklung zu den anspruchsvollsten Aufgaben zählt.

Üblicherweise sperrt der Prozessor den Interrupteingang mit dem 
Auftreten eines Interrupts und gibt ihn erst am Ende der 
Interruptroutine wieder frei (daher MUSS man diese mit IRET o.ä. 
beenden), eine 2. Ereignis bewirkt daher je nach Hardware garnichts oder 
einen unmittelbar folgenden erneuten Aufruf der Interruptroutine. Dieses 
Verhalten kann man aber auch ändern, etwa indem man per Software den 
Interrupt wieder aktiviert, so dass der 2. Interrupt auch innerhalb des 
1. ausgeführt wird - ob das eine gute Idee ist, ist eine andere Frage. 
Jedenfalls hilft dabei wie üblich beim Programmieren sorgfältiges 
Nachdenken darüber, was genau abläuft.

Dass ausserdem noch eine Prioritätsverwaltung verschiedener Interrupts 
mitspielt, lasse ich mal weg, das würde hier zu weit führen.

Gruss Reinhard

von spess53 (Gast)


Lesenswert?

Hi

>Ein Unterprogramm, kein Interrupt !, braucht keine Push und POP Befehle.
>Hier ist der Aufruf ja an einer bekannten Stelle im Programm.

Wenn ich eine Bibliothek für z.B. ein Display programmiere, die in 
verschiedenen Programmen eingesetzt werden soll, weiss ich noch nicht 
aus welchem Kontext heraus ein Unterprogramm aufgerufen wird.

Deine Aussage ist maximal für kleinere Programme bedingt gültig.

MfG Spess

von oldmax (Gast)


Lesenswert?

Hi Spess
Meine Aussage ist gültig, da du weiterlesen solltest. Es ist nicht 
verboten, Push und POP zu nutzen, doch es ist in der Regel nicht 
erforderlich. Bei einem Unterprogrammaufruf mit RCALL oder CALL durch 
den Programmierer ist doch der Programmbereich definiert. Und mit RET 
gehts da wieder weiter. Also, der Programmierer weiß doch, von wo aus 
das UP aufgerufen wird. Hat er da irgendwelche Registerwerte, die er 
nach der Routine noch braucht, dann nutzt er Push und POP, sonst nicht. 
Bei einem Interrupt hingegen weiß der Programmierer nicht, welche 
Bearbeitung gerade durchgeführt hat. Ergo MUSS er die Register sichern.
Ich kenn das noch aus Z80 Zeiten. Da war auch ein bedingter Call 
möglich. Brauchte man nach dem UP noch die Statusbits aus dem vorherigen 
Vergleich, hat man diese auch zwischengespeichert.
Außerdem, sicherlich laufen unsere Gedanken konform, sitzen auf der 
anderen Seite Schüler, die mal was von Interrupt und Stack gehört haben. 
So Feinheiten und Tricks, die ein Profi anwenden könnte, würden doch 
hier das Verständnis überfordern. Ich möcht jetzt noch nicht auseinander 
klamüsern, was ein großes und was ein kleineres Programm ist. Ich glaub, 
um einen Atmega8 zu 80% mit Assemblercode zu füllen ist keine kleine 
Anwendung, es sei denn ich hab da viel unsinnig Zeug drin, was nur den 
Code aufbläht. Aber das kennst du selbst am besten.
 Gruß oldmax

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

oldmax schrieb:
> Also, der Programmierer weiß doch, von wo aus
> das UP aufgerufen wird.

Nein, das weiß der Programmierer einer Bibliothek (z.B. 
Display-Routinen) eben nicht. Genau das hat Spess gesagt.

von Sam .. (sam1994)


Lesenswert?

Ich denke oldmax geht es hier eher um selbstgeschriebene Unterprogramme. 
Meine Unterprogramme in ASM überschreiben auch meistens bestimmte 
Register. Als Programmierer weiß ich das und schreibe das Hauptprogramm 
so das nichts überschrieben wird. Diese bestimmten Register sind 
natürlich meistens die gleichen.

von Reinhard Kern (Gast)


Lesenswert?

oldmax schrieb:
> Also, der Programmierer weiß doch, von wo aus
> das UP aufgerufen wird.

Also wenn du Unterprogramme schreibst, die nur von einer Stelle aus 
aufgerufen werden, hast du den Sinn von Unterprogrammen im Allgemeinen 
und von Bibliotheken im Besonderen wohl nicht verstanden. Da könntest du 
auch ein Include einsetzen und auch noch Call und Ret einsparen.

Ich gehe mal davon aus, dass du das nicht wirklich so gemeint hast wie 
es dasteht.

Gruss Reinhard

von Maik M. (myco)


Lesenswert?

Samuel K. schrieb:
> Ich denke oldmax geht es hier eher um selbstgeschriebene Unterprogramme.
> Meine Unterprogramme in ASM überschreiben auch meistens bestimmte
> Register. Als Programmierer weiß ich das und schreibe das Hauptprogramm
> so das nichts überschrieben wird. Diese bestimmten Register sind
> natürlich meistens die gleichen.

Unterprogramme schreibt man in der Regel nur wenn man sie öfters, an 
mehreren Stellen braucht, daher macht es eigentlich garkeinen Sinn, im 
Hauptprogramm Register zu sichern und wiederherzustellen, weil man dann 
unnötig Platz verschwendet. Normalerweise macht man das in 
Unterprogrammen, und dann braucht man sich auch niewieder Gedanken um 
das Unterprogramm zu machen, es reicht allein, zu wissen was an 
Parameter reinkommen und was das Unterprogramm macht. Man muss meistens 
nicht wissen, wie es das macht.

von Sam .. (sam1994)


Lesenswert?

Meine Unterprogramme sind z.B Divisionen, BCD-Konvertierungen, 
TWI-Senderoutinen... Das braucht man schon öfters. Das Hauptprogramm 
muss beim Aufruf der Divisionroutine bspw. dafür sorgen, dass in den 
Registern r22-r25 keine relevanten Daten sind.

Maik M. schrieb:
> im
> Hauptprogramm Register zu sichern und wiederherzustellen, weil man dann
> unnötig Platz verschwendet.

Im Hauptprogramm werden fast keine Register gesichert. Wenn überhaupt 
dann mit movw. Das Hauptprogramm arbeitet normalerweise mit den Register 
r0-r18 + Pointer. Die restlichen Register werden nur temporär genutzt. 
Diese stehen den Funktionen zu.

Wer alle 32 Register gleichzeitig braucht, schreibt entweder 
hochoptimiert oder sollte sich das Konzept nochmal überlegen.

von MCUA (Gast)


Lesenswert?

>Ein Interrupt ist ein Sonderfall eines Unterprogrammes.
Nein, ein Interrupt hat mit einem Programmteil überhaupt nichts zu tun.
Es ist nur irgent ein Trigger. Es kann sein, dass dadurch nur interne 
Perif. ausgelöst wird, ohne dass die CPU überhaupt was macht.


>Alle Register, die in einer Interruptbearbeitung benutzt werden, müssen
>zwischengespeichert werden.
Nicht, wenn eine andere RegisterBank benutzt wird.
(Dann muss (ggfs) nur die BankNr gesichert werden)

>Bei einem Interrupt hingegen weiß der Programmierer nicht, welche
>Bearbeitung gerade durchgeführt hat. Ergo MUSS er die Register sichern.
Sofern die (ASM)Befehle überhaupt Register (in der gleichen Bank) 
benutzen.


>Würde ich also 500 Befehle in diesen Interrupt packen, wär
>für's Hauptprogramm keine Zeit mehr.
Manche "Hauptprogramme" machen gar nix, ausser auf Interrupts zu warten.


>Ich kenn das noch aus Z80 Zeiten.
So alt sind die Zeiten gar nicht, siehe RL78.


>Dass ausserdem noch eine Prioritätsverwaltung verschiedener Interrupts
>mitspielt, lasse ich mal weg, das würde hier zu weit führen.
Das hat aber fast jede CPU.

von Peter D. (pdiener) Benutzerseite


Lesenswert?

>Also, der Programmierer weiß doch, von wo aus
>das UP aufgerufen wird. Hat er da irgendwelche Registerwerte, die er
>nach der Routine noch braucht, dann nutzt er Push und POP, sonst nicht.
>Bei einem Interrupt hingegen weiß der Programmierer nicht, welche
>Bearbeitung gerade durchgeführt hat. Ergo MUSS er die Register sichern.

Normalerweise weiß der Programmierer eines Unterprogramms nicht, aus 
welchem Kontext es aufgerufen wird. Dafür ist ein Unterprogramm ja da, 
dass man sich eben nachträglich noch überlegen kann, wo man es überall 
brauchen kann.

Das mit dem Sichern der Register geht normal andersrum. Man sichert 
nicht diejenigen, die man nach dem ret noch braucht, sondern man sichert 
diejenigen, die man selbst im Unterprogramm lokal braucht und daher 
verändert.

Alle Register, die man dort nicht anfasst, braucht man auch nicht 
sichern, sie behalten einfach ihren Wert. Alle, Register, die man im 
Unterprogramm benutzen will, werden vorher gesichert und vor dem ret 
wieder hergestellt.

Dieses Konzept ist sparsam im Stackverbrauch und ohne größere 
Komplexität problemlos in beliebiger Schachtelungstiefe anwendbar, auch 
bei Rekursionen.

Grüße,

Peter

von Sam .. (sam1994)


Lesenswert?

Der C-Compiler stellt für die Unterprogramme übrigens generell 16 
Register frei. Auch hier muss er die Register vor dem Aufruf sichern. 
Sie werden nicht im Unterprogramm gesichert.
Der Vorteil dabei ist, dass bei nicht rekursiven Funktionen das Sichern 
meistens wegfällt.

von Reinhard Kern (Gast)


Lesenswert?

Samuel K. schrieb:
> Der C-Compiler stellt für die Unterprogramme übrigens generell 16
> Register frei.

Ganz bestimmt nicht, höchstens für deinen speziellen Prozessor und 
deinen speziellen Compiler, mit deiner speziellen Einstellung - 
wahrscheinlich hast du noch nichts anderes kennengelernt. Es gibt aber 
unzählige Registerkonzepte und dazu noch verscheidenste C-Compiler, und 
manche Prozessoren haben noch nicht mal 16 Register. Da hilft nur RTFM, 
Abschnitt Interfacing to Assembler, da muss drinstehen, wie der Compiler 
Unterprogramme und Interruptroutinen aufruft.

Es gibt auch ganz andere Konzepte, Sparc-Prozessoren z.B. rotieren statt 
dessen Registerbänke und sind auch daher besonders schnell. Und auch 
schon beim Z80 konnte man einen Interrupt mit dem alternativen 
Registersatz ausführen und sich damit die ganze Popperei sparen, wie 
hier schon mal erwähnt.

Sicher ist nur eines: ein C-Compiler, der einen fixen Registersatz 
freistellt, arbeitet nicht optimal. Es könnten ja leicht von den 16 
gesicherten Registern 14 überflüssig sein. Das ist also höchstens ein 
Compiler für minderbemittelte Programmierer, vermutlich stimmt also die 
Angabe sowieso nicht.

Gruss Reinhard

von Reinhard Kern (Gast)


Lesenswert?

Peter Diener schrieb:
> Dieses Konzept ist sparsam im Stackverbrauch und ohne größere
> Komplexität problemlos in beliebiger Schachtelungstiefe anwendbar, auch
> bei Rekursionen.

Das meinst du nicht im Ernst - eine beliebig tiefe Stackbelegung würde 
die Informatik revolutionieren, das wäre ja praktisch ein Computer mit 
unendlichem Speicher.

Gruss Reinhard

von Sam .. (sam1994)


Lesenswert?

Ja ich korrigere auf den freien C-Compiler für Avr.

Reinhard Kern schrieb:
> Das ist also höchstens ein
> Compiler für minderbemittelte Programmierer, vermutlich stimmt also die
> Angabe sowieso nicht.

avrgcc für minderbemittelte Programmierer... aha

Es sind übrigens 14 (inkl. R1) Register, da habe ich mich verzählt.

Reinhard Kern schrieb:
> Das meinst du nicht im Ernst - eine beliebig tiefe Stackbelegung würde
> die Informatik revolutionieren, das wäre ja praktisch ein Computer mit
> unendlichem Speicher.

Bist du immer so spitzfindig? Dass es oben um einen C-Compiler für avr 
geht, hätte man auch aus dem Kontext entziehen können und so viele 
C-Compiler für Avr gibt es schließlich nicht.

von Reinhard Kern (Gast)


Lesenswert?

Samuel K. schrieb:
> Es sind übrigens 14 (inkl. R1) Register, da habe ich mich verzählt.

Da würde ich drauf wetten, dass bei einem realen Programm mehr als die 
Hälfte überflüssig ist, das ist bei einem Ebedded Programm untragbar - 
ein 8051 z.B. hat eine Stacktiefe von 256 Bytes, oder er wird langsam in 
der Ausführung durch XMEM-Zugriffe. Gerade mit dem Stack muss man da 
sparsam umgehen. Eigentlich sollte ein hochoptimierender Compiler 
keinerlei überflüssige Codeteile einfügen, sonst ist er gegenüber 
Assembler-Programmierung nicht konkurrenzfähig.

Gruss Reinhard

PS Zitat aus Gnu CC: If you enable it, GCC can save registers around 
function calls.

von spess53 (Gast)


Lesenswert?

Hi

>Es sind übrigens 14 (inkl. R1) Register, da habe ich mich verzählt.

Habe ich bei meinen Versuchen mit GCC nicht feststellen können. Und bei 
den hier veröffentlichten disassemblierten Code habe ich das auch noch 
nicht gesehen. Irgend etwas machst du falsch.

MfG Spess

von Sam .. (sam1994)


Lesenswert?

http://www.rn-wissen.de/index.php/Avr-gcc/Interna

R0, R18 – R27, R30, R31
    können durch Funktionsaufrufe verändert werden, ohne restauriert zu 
werden

von Dietrich L. (dietrichl)


Lesenswert?

MCUA schrieb:
>>Ein Interrupt ist ein Sonderfall eines Unterprogrammes.
> Nein, ein Interrupt hat mit einem Programmteil überhaupt nichts zu tun.

Beides stimmt:

Man kann eine Interrupt durchaus "ein durch die Hardware aufgerufenes 
Unterprogramm" nennen. Es laufen die gleiche Mechanismen ab bzgl. 
Adresse auf Stack sichern und Rückkehr zur Stelle der Unterbrechung.

Und es wird nicht von einem Programm aufgerufen (Ausnahme: so genannte 
Software-Interrupts, die hier aber nur Verwirrung stiften).

Gruß Dietrich

von Reinhard Kern (Gast)


Lesenswert?

Samuel K. schrieb:
> R0, R18 – R27, R30, R31
>     können durch Funktionsaufrufe verändert werden, ohne restauriert zu
> werden

Das muss nicht heissen, dass die gesichert werden (wie du behauptet 
hast), das kann genausogut heissen, dass sie der C-Compiler überhaupt 
nicht verwendet.

Gruss Reinhard

von Sam .. (sam1994)


Lesenswert?

> Das muss nicht heissen, dass die gesichert werden (wie du behauptet
> hast), das kann genausogut heissen, dass sie der C-Compiler überhaupt
> nicht verwendet.

Mit sichern meine ich relevante Daten sichern und nicht irgendetwas 
unnötiges auf den Stack legen.

von oldmax (Gast)


Lesenswert?

Hi
So langsam artet dieser Tread aus und wird zur unerträglichen 
Diskussionsebene von Experten. Habt ihr eigentlich das gelesen ?


>ahhh ok, ich meine ich habs geschnallt.

>Ich bin jetzt nur auf die Frage gekommen weil unsere Leherer damals
>gemeint hat das man die Interrupt Routine so kurz wie möglich halten
>sollte und man keine Unterprogramme aufrufen sollte.

Nun noch einmal zu euren durchaus hilfreichen Antworten. Meint ihr, das 
es  hier Sinn macht von Bibliotheken und Kontext, von C-Compilaten und 
Schachtelungstiefen von Unterprogrammen zu schreiben. Mal ehrlich, was 
glaubt ihr, hat euer fachgesimpel dem OZT gebracht ?
Verwirrung, würd ich sagen.
Also mal ehrlich, Herr Kern und Herr Spess und wer auch immer auf diesen 
Zug aufgesprungen ist. Niemand bezweifelt doch eure Fähigkeiten, aber 
was Hilfe für einen Anfänger betrifft, vermutlich Schüler, der von 
seinen Lehrern auch noch kräftig mit absoluter Fachkompetenz unterstützt 
wird, steht ihr noch ganz weit unten in der Kette... Ein wenig mehr 
Erfahrung diesbezüglich hätte ich euch schon zugetraut, aber so ist das 
eben mit der Einbildung, besser zu sein.
Sorry JSP, das eine so kurze Frage so verwirrende Antworten liefern 
kann. Wenn sich die Experten mal wieder beruhigt und besonnen haben, 
werden sie auch wieder verwertbare Information liefern.
Gruß oldmax

von Reinhard Kern (Gast)


Lesenswert?

oldmax schrieb:
> Ein Unterprogramm, kein Interrupt !, braucht keine Push und POP Befehle.
> Hier ist der Aufruf ja an einer bekannten Stelle im Programm.

Bloss weil die Experten festhestellt haben, dass du da blanken Mist 
geschrieben hast, sind jetzt plötzlich alle weiteren Erläuterungen 
schädlich für die Diskussion. Vielleicht für dein Ego, aber nicht für 
das Verständnis von Stack usw.

Gruss Reinhard

von Peter D. (pdiener) Benutzerseite


Lesenswert?

Reinhard Kern schrieb:
> Peter Diener schrieb:
>> Dieses Konzept ist sparsam im Stackverbrauch und ohne größere
>> Komplexität problemlos in beliebiger Schachtelungstiefe anwendbar, auch
>> bei Rekursionen.
>
> Das meinst du nicht im Ernst - eine beliebig tiefe Stackbelegung würde
> die Informatik revolutionieren, das wäre ja praktisch ein Computer mit
> unendlichem Speicher.
>
> Gruss Reinhard

Ich meine beliebig im Sinne von frei wählbar, nicht im Sinne von 
unendlich. Natürlich ist irgendwann der Speicher voll...

Was ich meine, ist dass es gleichermaßen mit einem einzelnen Aufruf wie 
auch mit einer x-fachen Rekursion funktioniert, ohne dass man das 
KONZEPT des Registersicherns ändern muss. Selbstverständlich gehe ich 
davon aus, dass man darüber nachdenkt, wieviel Speicher das braucht und 
ob der ausreicht.

Grüße,

Peter

von oldmax (Gast)


Lesenswert?

Hi
Vielleicht sollten wir ein wenig runterkommen. Mittlerweile beginnt das 
Thema, die Gürtellinie zu erreichen. Ich werd mich jetzt nicht 
herablassen, da weiter drauf einzugehen. Ausgang war doch die Frage:
>und zwar wio oft darf ich in einem Unterprogramm ein Unterprogramm
>aufrufen (rcall)? (ich meine in einen rcall ein rcall auffrufen)
>Und wie groß dürfen die Unterprogramme sein?

Und die Antwort ist doch eigentlich ganz einfach, auch wenn es 
programmtechnisch Blödsinn ist.
Ein unterprogramm kann beliebig oft Unterprogramme aufrufen. Die Grenze 
setzt der Stack, da er irgendwann mal überläuft und ein Programm ins 
Nirwana schickt.
Die Größe eines Unterprogrammes kannebenfalls fast den gesamten Speicher 
belegen.
BSPL.
1
Loop
2
  RCALL MY_Great_Sub
3
RJMP Loop
4
5
My_Great_Sub:
6
  .....
7
  ....
8
RET
Das ist Quatsch, aber durchaus nicht verboten und es funktioniert! Die 
Frage bezog sich auch auf Assembler und nicht auf C-Compiler. 
Allerdings, auch da wär ein solches Konstrukt möglich.
Wenn jemand mehr über Programme und Strukturen wissen möchte.... ich 
helfe gern. Allerdings, wer meine Texte als blanken Mist empfindet, hmm, 
ist mir ehrlich gesagt auch egal. Mein Ego orientiert sich an ganz 
anderer Stelle.
Gruß oldmax

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.