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


von Erdbewohner (Gast)


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

von Flo (Gast)


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"

von Wahrsager (Gast)


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!

von Murkser (Gast)


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

von Yalu X. (yalu) (Moderator)


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.

von Erdbewohner (Gast)


Angehängte Dateien:

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

von Иван S. (ivan)


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

von Maik F. (sabuty) Benutzerseite


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

von Erdbewohner (Gast)


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

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.