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?
??? 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
Je nachdem, manche Pics hatten/haben? Hardwarestacks für Unterfunktionsaufrufe. Da war/ist es klar auf die Stacktiefe beschränkt.
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.
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
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.
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.
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.
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.
ja stimmt, so hat er es auch glaub ich gemeint. Danke an alle
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.
> 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.
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!
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
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
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
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
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.
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.
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
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.
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.
>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.
>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
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.
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
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
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.
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.
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
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
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
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
> 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.
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.