www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik rekursiver Funktionsaufruf verbraucht 1814 Bytes??


Autor: Erdbewohner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo
Ich möchte ein art Betriebssystem programmieren, das ein programm in 
extrem einfacher und selbst entwickelten sprache ausführt. Dazu habe ich 
eine Funktion geschrieben, die ein gigantisches switch (153 cases) 
enthält, ein case für jeden Programmbefehl (von meiner eigenen sprache).
Nun möchte ich die funktion am ende rekursiv aufrufen, sodass die 
Befehle nach einander abgearbeitet werden.
Da die funktion ausser in den Cases einzelne lokale variablen keine 
variablen enthält, sollte das mit dem SRAM gehen, ausserdem sollten die 
einzelnen Teilprogramme nicht so lang sein.
Nun zu meinem Problem:
als ich das komplette switch programmiert hatte, war der programmcode 
2996 bytes gross. Als ich dann die zeile, wo sich die Funktion selbst 
aufruft (mit 2 parametern) einfügte, war das programm plötzlich 4810 
bytes gross!!
Wie kann das sein??
Arbeite mit obtimierung s

Gruss Erdbewohner

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie wärs auf die Rekursion zu verzichten und das ganze in ne Schleife zu 
packen:

schleife
  werte befehl aus
solange nicht programmende:
  spring nach "schleife"

Autor: Wahrsager (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine Kristallkugel streikt neuerdings am Sonntag,
hat wohl die Zeitumstellung nicht vertragen.

Poste doch mal den Code, dann wird geholfen.

Rekursives Aufrufen von Funktionen verbrät (gerne)
Speicher, denn die Variablen des vorigen Aufrufe
sollte wohl erhalten bleiben, und wenn das viele sind.....

Schönen Sonntag noch!

Autor: Murkser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

> Ich möchte ein art Betriebssystem programmieren, das ein programm in
> extrem einfacher und selbst entwickelten sprache ausführt. Dazu habe ich
> eine Funktion geschrieben, die ein gigantisches switch (153 cases)
> enthält, ein case für jeden Programmbefehl (von meiner eigenen sprache).

Du willst also einen Interpreter für Deine Sprache bauen.

> Nun möchte ich die funktion am ende rekursiv aufrufen, sodass die
> Befehle nach einander abgearbeitet werden.

Das ist keine gute Idee. Du gehst also pro Instruktion Deines 
interpretierten Programms einen Schritt tiefer in Deiner 
Rekursionshierarchie? Das ist ein Riesenaufwand, ganz zu schweigen von 
dem unbegrenzten Wachstum des Stacks. Normalerweise wird ein (simpler) 
Interpreter mit einem großen Switch-Befehl in einer Schleife 
verwirklicht. In jeder Iteration holst Du Dir die nächste Instruktion, 
dekodierst sie und führst dann die jeweilige Aktion aus. Dann schaust Du 
wo es im Kontrollfluß weitergeht und gehst in die nächste Iteration.

> als ich das komplette switch programmiert hatte, war der programmcode
> 2996 bytes gross. Als ich dann die zeile, wo sich die Funktion selbst
> aufruft (mit 2 parametern) einfügte, war das programm plötzlich 4810
> bytes gross!!
> Wie kann das sein??

Naja, für Deine Rekursion muß schon ganz schön Aufwand getrieben werden, 
den Call Stack jedesmal zu sichern und den Kontext der aufrufenden 
Funktion bei der Rückkehr wiederherzustellen. Ich sehe aber wie oben 
geschrieben keinen Grund Deinen Interpreter rekursiv zu bauen. Im 
Gegenteil, vermeide dies auf jeden Fall!

Alles Gute,
Murkser

Autor: Yalu X. (yalu) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal abgesehen vom Sinn¹ oder Unsinn, eine Schleife als Rekursion zu
schreiben:

Wenn der Programmcode durch Hinzufügen einer (scheinbar) einfachen
Anweisung stark wächst, hat dies i.Allg. eine der folgenden Ursachen:

- Die zusätzliche Anweisung ruft direkt oder indirekt eine Bibliotheks-
  funktion auf, die sonst nirgends im Programm verwendet wird. Ein indi-
  rekter Aufruf einer Bibliotheksfunktion passiert bspw. auch dann, wenn
  die Anweisung Floating-Point-Operationen enthält.

- Der Compiler kann ohne die zusätzliche Anweisung große Teile des Codes
  wegoptimieren, weil dieser dann nichts Sinnvolles tut.

In deinem Fall würde ich auf die zweite Ursache tippen.


¹) In manchen Programmiersprachen sind ja Schleifen schlechter Program-
   mierstil. Ich nehme aber an, dass du keine dieser Sprachen benutzt.


Edit:

> Nun möchte ich die funktion am ende rekursiv aufrufen, sodass die
> Befehle nach einander abgearbeitet werden.

Wenn der rekursive Aufruf wirklich die letzte Aktion in der Funktion
ist, also eine so genannte Endrekursion vorliegt, wird er von besseren
Compilern automatisch in eine Schleife umgesetzt. Trotzdem sollte man in
imperativen Sprachen in solchen Fällen die Schleife direkt als solche
hinschreiben.

Autor: Erdbewohner (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Danke für die Tipps!
Ich habe das ganze nun mal in eine endlos schleife gemacht. Wenn mein 
Programmteil fertig ist, gibt es einfach einen return.
Nur: die Codegrösse ist immer die gleiche, ob mit schleife (main) oder 
rekursion (main2).
Den Code habe ich angehängt.
Erdbewohner

Autor: Иван S. (ivan)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Yalu X. schrieb:
> ¹) In manchen Programmiersprachen sind ja Schleifen schlechter Program-
>    mierstil. Ich nehme aber an, dass du keine dieser Sprachen benutzt.

-v, bitte. Das  interessiert mich jetzt welche Sprache(n) hier gemeint 
sein koennten.

Iwan

Autor: Maik Fox (sabuty) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Иван S. schrieb:
> Yalu X. schrieb:
>> ¹) In manchen Programmiersprachen sind ja Schleifen schlechter Program-
>>    mierstil. Ich nehme aber an, dass du keine dieser Sprachen benutzt.
>
> -v, bitte. Das  interessiert mich jetzt welche Sprache(n) hier gemeint
> sein koennten.
>
> Iwan

http://de.wikipedia.org/wiki/Funktionale_Programmierung

Autor: Erdbewohner (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, Yalu!
Du hattes recht. Ich hab es mal ohne optimierung compiliert und da war 
der unterschied nicht mehr da.
Wenn das programm dann nicht 600 takte zusätzlich macht (den grössten 
teil des switch überspringt er ja (hoffentlich)) bin ich ja beruhigt ;-)
Danke nochmal!
Gruss Erdbewohner

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.