Programmiersprache für self-modifying-code?
- Ich bin vor kurzem denken über das schreiben selbst modifizierende Programme, ich denke, es kann kraftvoll sein und Spaß machen. Also ich bin derzeit auf der Suche nach einer Sprache, können Sie ein Programm den eigenen code problemlos.
- Habe ich gelesen, C# (als Weg ringsherum) und die Möglichkeit zum kompilieren und ausführen von code in der runtime, aber das ist zu verletzen.
- Ich denke auch über Montage. Es ist einfacher, es zu ändern, ausführen von code, aber es ist nicht sehr mächtig (sehr roh).
Können Sie vorschlagen, eine mächtige Sprache oder feature unterstützt das ändern von code in der runtime?
Beispiel
Dass das, was ich meine, indem geändert wird, code in der runtime:
Start:
a=10,b=20,c=0;
label1: c=a+b;
....
label1= c=a*b;
goto label1;
und erstellen eine Liste von Anweisungen:
code1.add(c=a+b);
code1.add(c=c*(c-1));
code1. execute();
- Wollen Sie zum kompilieren/ausführen von code zur Laufzeit, oder wollen Sie zum ändern der ausführbaren Datei selbst, während es in den Speicher geladen werden: das sind zwei sehr verschiedene Dinge. (In der Regel "selbst-ändern" heißt der zweite)
- Danny Pflughoeft: ich bin interessiert in der zweiten.. Der erste ist gemeint, wenn das zweite nicht möglich ist oder nicht zur Verfügung ...
- Ich pflegte zu denken, über self-modifying code viel. Ich habe nie viel Verwendung für Sie, nachdem ich erfuhr, function-Pointer und Objekt-orientierten Sprachen. Sie haben keine Reale Verwendung dafür?
- bbbb: ich will eine solche Sprache zu lernen, zu entdecken der realen Welt genutzt!
- dynamische Programmierung ist eine Familie von minimzation/Maximierung Techniken. Es ist nichts mit dynamischen Sprachen/Eingabe. Irgendwie ein Nomenklatur problem...
- Nathan: tut mir Leid ich werde es beheben
- Redcode (vyznev.net/corewar/guide.html) , viele der besten Krieger sind self-modifing...
- Bei der Interpretation Sprachen, es ist weit von Hexenwerk - bauen Sie das Programm als generator der code und die eval()-es. Die Dinge sind weit mehr interessante und komplexe, die in kompilierten Sprachen. Sie müssen wissen, zugrunde liegende Schicht (Zusammenbau oder Besondere byte-code), um es zu manipulieren. Ich bin mir nicht sicher, aber vielleicht alternative sind erwähnenswert, z.B. indem Sie eine Logik in DLLs (oder COM-Server) und erstellen Sie den Programmablauf als die Reihe von entsprechenden invokations. PS: Sind nicht Sie denken, polymorphe Viren? man bekommt ziemlich viel interessante und schwierige Sachen auf, die Angelegenheit durch googeln
InformationsquelleAutor Betamoo | 2010-06-16
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Malbolge wäre ein guter Ort, um zu starten. Jeder Befehl ist, sich selbst zu ändern, und es ist eine Menge Spaß(*) zu spielen.
(*) Disclaimer: nicht wirklich Spaß.
Ich sehr empfehlen Lisp. Lisp-Daten gelesen werden können und exec würde als code. Lisp-code kann geschrieben werden als Daten.
Gilt es als eines der kanonischen selbst modifizierbar Sprachen.
Beispiel Liste(Daten):
oder aufrufen von Daten als code
läuft der + - Funktion.
Können Sie auch gehen, und Bearbeiten Sie die Mitglieder die Listen-on-the-fly.
edit:
Habe ich ein Programm geschrieben, um dynamisch erstellen Sie ein Programm und testen Sie es auf der fliege, dann um mir zu berichten, wie es im Vergleich zu einer baseline(div durch 0 war der übliche Bericht, ha).
Jede Antwort, so weit ist die über Reflexion/runtime compilation, aber in den Kommentaren erwähnten Sie, dass Sie interessiert sind, die tatsächlichen self-modifying code - code ändert sich in-memory.
Gibt es keine Möglichkeit, dies zu tun in C#, Java, oder auch (tragbar) in C - das heißt, Sie können nicht ändern, die geladenen in-memory-binary mit diesen Sprachen.
Im Allgemeinen, der einzige Weg, dies zu tun ist bei der Montage, und es ist sehr Prozessor-abhängig. In der Tat, es ist sehr vom Betriebssystem abhängig als auch: zum Schutz gegen polymorphe Viren, die meisten modernen Betriebssysteme (einschließlich Windows XP+, Linux und BSD) durchzusetzen W^X, das heißt, Sie müssen gehen Sie durch einige Schwierigkeiten zu schreiben polymorphe ausführbaren Dateien in die Betriebssysteme, für die, bei denen es überhaupt nicht.
Kann es möglich sein, in einigen Sprachen interpretiert zu haben, das Programm zu ändern, seinen eigenen source-code, während es läuft. Perl,
Python(siehe hier), und jede Implementierung von Javascript, die ich kenne, erlauben dies nicht, aber.Persönlich finde ich es sehr merkwürdig, dass Sie finden die Montage einfacher zu handhaben als C#. Ich finde es noch seltsamer, dass Sie denken, die Montage ist nicht so mächtig: Sie kann nicht stärker als raw-Maschinensprache. Sowieso, jedem das seine/Ihre eigene.
C# hat eine große Reflexion Dienste, aber wenn Sie haben eine Abneigung gegen das.. Wenn Sie sind wirklich komfortabel mit C oder C++, können Sie immer ein Programm schreiben, schreibt C/C++ und Probleme, die es zu einem compiler. Dies wäre nur dann lebensfähig, wenn Ihre Lösung nicht erforderlich, einen schnellen self-umschreiben von turn-around-Zeit (in der Größenordnung von zehn Sekunden oder mehr).
Javascript-und Python-Unterstützung-Reflexion. Wenn Sie jetzt denken, lernen eine neue, lustige Programmiersprache, die mächtig, aber nicht Massiv technisch anspruchsvoll, dann empfehle ich Python.
Darf ich vorschlagen,Python, ein schönes sehr hohe dynamische Sprache, die reiche Introspektion enthalten (und durch z.B. die Verwendung der
compile
,eval
oderexec
ermöglicht eine form der self-modifying-code). Ein sehr einfaches Beispiel, basierend auf Ihre Frage:Beachten Sie, dass im code-Beispiel oben
c
ist nur verändert in der Funktion Bereich.Common Lisp wurde speziell für diese Art der Sache im Auge. Sie könnten auch versuchen,Smalltalk, wo mit der Reflexion zu ändern, ausführen von code ist nicht unbekannt.
In beiden Sprachen, die Sie wahrscheinlich sind, zu ersetzen eine ganze Funktion oder eine ganze Methode, nicht eine einzige Zeile code. Smalltalk-Methoden neigen dazu, mehr feinkörniger als Lisp-Funktionen, so dass möglicherweise ein guter Ort, um zu beginnen.
Viele Sprachen lassen Sie eval code zur Laufzeit.
In der high-level-Sprachen, wo Sie kompilieren und ausführen von code zur Laufzeit ist es nicht eigentlich self-modifying code, aber dynamische laden von Klassen. Mit der Vererbung Prinzipien, kann man ersetzen, eine class Factory, und ändern Sie das Verhalten der Anwendung zur Laufzeit.
Nur in Assembler haben Sie wirklich wahre selbst-Modifikation, die durch das schreiben direkt auf dem code-segment. Aber es gibt wenig praktische Verwendung für Sie. Wenn Sie eine Herausforderung mögen, schreiben Sie eine self-encrypting, vielleicht polymorphe virus. Das würde Spaß machen.
Ich schrieb Python-Klasse Code, der ermöglicht Ihnen das hinzufügen und löschen neue Zeilen code, um das Objekt, drucken Sie den code und excecute es. Klasse Code am Ende angezeigt.
Beispiel: wenn x == 1, der code ändert seinen Wert für x = 2 und löscht dann wird der ganze block mit der bedingten, die überprüft die Bedingung.
Nachdem der code erstellt wurde, können Sie es drucken:
Ausgabe:
Führen cade durch den Aufruf des Objekts: code()
Ausgang 2:
Wie Sie sehen können, ist der code verändert die variable x auf den Wert 2 gelöscht und die ganzen if-block. Dies kann hilfreich sein, um zu vermeiden, überprüfen von Bedingungen, sobald Sie erfüllt sind. Im real-life, in diesem Fall gehandhabt werden kann, indem eine koroutine, aber dieses self-modifying-code-experiment ist nur zum Spaß.
Ich manchmal, obwohl sehr selten self-modifying-code in Ruby.
Manchmal muss man eine Methode, wo Sie nicht wirklich wissen, ob die Daten, die Sie verwenden (z.B. einige faule cache) richtig initialisiert sind oder nicht. Also, Sie haben, um überprüfen am Anfang der Methode, ob die Daten ordnungsgemäß initialisiert und dann vielleicht initialisieren. Aber Sie ist wirklich nur zu tun haben, dass die Initialisierung nur einmal, aber Sie überprüfen Sie es jedes einzelne mal.
So, manchmal Schreibe ich eine Methode, die die Initialisierung und dann ersetzt sich selbst mit einer version, die nicht enthalten den Initialisierungscode.
Aber ganz ehrlich, ich glaube nicht, dass ist es Wert. In der Tat, ich bin beschämt zugeben, dass ich nie wirklich gemessen, um zu sehen, ob das eine bedingte macht eigentlich keinen Unterschied. (Auf eine moderne Ruby-Implementierung mit einem aggressiv Optimierung von Profil-feedback-getriebene JIT-compiler wahrscheinlich nicht).
Beachten Sie, dass, je nachdem, wie Sie definieren "self-modifying code", dies kann oder kann nicht sein, was Sie wollen. Sie sind ersetzen einen Teil der derzeit auszuführende Programm, also ...
EDIT: Jetzt, wo ich darüber nachdenke, dass die Optimierung nicht so viel Sinn. Die teure Initialisierung wird nur einmal ausgeführt, sowieso. Das einzige, was Veränderung verhindert, ist das an Bedingungen geknüpft ist. Es wäre besser, ein Beispiel nehmen, wo die Prüfung sich ist teuer, aber ich kann nicht von einem denken.
Aber ich dachte an ein cooles Beispiel für self-modifying-code: die Maxine JVM. Maxine ist ein Forschungs-VM (ist es technisch eigentlich nicht erlaubt, um als ein "JVM", da die Entwickler nicht ausgeführt, die Kompatibilität testsuites) geschrieben völlig in Java. Nun, es gibt viele JVMs geschrieben, in sich selbst, aber Maxine ist die einzige, die ich kenne, die auch läuft in sich selbst. Dieses ist extrem leistungsfähig. Zum Beispiel, der JIT-compiler JIT-Kompilierung sich um eine Anpassung an die Art von code, es ist die JIT-Kompilierung.
Sehr ähnlich, was passiert in der Klein VM was ist eine VM für das Selbst-Programmieren Sprache.
In beiden Fällen, die VM kann optimieren und neu kompilieren sich zur Laufzeit.
Können Sie dies tun, Maple (computer-algebra-Sprache). Im Gegensatz zu den vielen Antworten über die Verwendung kompilierter Sprachen, die nur erlauben Ihnen das erstellen und link im neue - code zur Laufzeit, hier kann man ehrliche-to-Güte ändern Sie den code der einem derzeit ausgeführten Programm. (Ruby und Lisp, wie von anderen Beantworter, können Sie auch dies tun; wahrscheinlich Smalltalk zu).
Eigentlich, früher war es standard in Ahorn, dass die meisten library-Funktionen wurden kleine stubs, die wäre laden Ihre "echte" selbst von der Festplatte auf den ersten Anruf, und dann von selbst ändern sich die version geladen. Ist dies nicht mehr der Fall, da die Bibliothek laden wurde virtualisiert.
Wie andere haben darauf hingewiesen: Sie müssen eine interpretierte Sprache mit starker Reflexion und verdinglichung Einrichtungen zu erreichen.
Ich geschrieben habe, eine automatisierte normalizer/simplificateur für Maple-code, die ich Fort zu laufen, auf die gesamte Bibliothek (einschließlich sich selbst); und da war ich nicht so vorsichtig sein, in all meinem code, der normalizer hat ändern sich. Ich schrieb auch einen Partielle Evaluator (vor kurzem angenommen durch SCP) genannt MapleMIX - auf sourceforge verfügbar - konnte aber nicht so ganz für voll zu sich selbst (das war nicht das design-Ziel).
Haben Sie schaute auf Java ? Java 6 hat eine compiler-API, so können Sie code schreiben und kompilieren Sie es in der Java-VM.
In Lua, können Sie den "Haken" bestehenden code, der ermöglicht Ihnen das Anhängen beliebiger code-Funktion aufruft. Es geht so etwas wie dieses:
Können Sie auch einfach Pflug über Funktionen, welche Art von gibt Ihnen, sich selbst zu ändern code.
In M. I. C. G. B. F., es ändert sich der interpreter jedesmal, wenn Sie es ausführen.
Es ist auch sehr lustig* zu Programm.
*Haftungsausschluss: Es kann nicht sein, Spaß, Programm in.