Frage

Ich brauche Code zu optimieren Raum für etwas neuen Code zu erhalten. Ich habe nicht den Raum für alle Änderungen. Ich kann nicht Code Bankumschaltung (80C31 mit 64k) verwenden.

War es hilfreich?

Lösung

Sie haben nicht wirklich viel gegeben hier zu gehen, aber es gibt zwei Hauptebenen Optimierungen können Sie prüfen:

Micro-Optimierungen:   z.B. XOR A anstelle von MOV A, 0   Adam hat einige dieser schön früher abgedeckt.

Makro-Optimierungen:   Schauen Sie sich die Struktur des Programms, die Datenstrukturen und Algorithmen verwendet, die Aufgaben durchgeführt und denken sehr intensiv darüber, wie diese neu angeordnet werden könnten oder sogar entfernt. Gibt es ganze Stücke von Code, der tatsächlich nicht verwendet? Ist Ihr Code voller Debug-Output-Anweisungen, dass der Benutzer nie sieht? Gibt es Funktionen, die spezifisch für einen einzelnen Kunden, die Sie aus einer allgemeinen Freigabe verlassen könnten?

Um einen guten Griff auf das bekommen, müssen Sie herausfinden, wo Ihr Speicher verbraucht wird. Die Linkers Karte ist ein guter Ort, um mit diesem zu beginnen. Makro-Optimierungen sind, wo die großen Gewinne gemacht werden können.

Als Nebenwirkung, man kann - versuchen seriously- Teile des Codes mit einem guten optimierenden C-Compiler neu zu schreiben. Sie können sich, wie eng der Code erstaunt sein, sein kann. Ein echter Assembler hotshot kann in der Lage sein, auf sich zu verbessern, aber es kann leicht besser als die meisten Programmierer. Ich benutzte die IAR ein etwa 20 Jahre her, und es blies meine Socken aus.

Andere Tipps

Mit Assembler-Sprache, werden Sie von Hand zu optimieren haben. Hier sind ein paar Techniken:

. Hinweis: IANA8051P (Ich bin kein 8501 Programmierer, aber ich habe eine Menge Montag auf anderen 8-Bit-Chips getan)

den Code Gehen Sie durch für alle duplizierten Bits suchen, egal wie klein und sie Funktionen machen.

einige der ungewöhnlicheren Anleitung lernen und sehen, ob Sie sie optimieren können, um zB. Ein schöner Trick ist XOR A zu verwenden, um den Akkumulator statt MOV A zu löschen, 0 -. Es speichert einen Byte

Ein weiterer netter Trick ist, wenn Sie eine Funktion vor der Rückkehr rufen, springen, nur um es zB statt:

CALL otherfunc
RET

Just tun:

JMP otherfunc

Achten Sie stets darauf relativ Sprünge und Verzweigungen, wo immer möglich machen, benutzen sie weniger Speicher als absolute Sprünge.

Das ist alles, was ich von aus der Spitze von meinem Kopf für den Moment denken kann.

Sorry, ich komme zu diesem späten, aber ich hatte einmal genau das gleiche Problem, und es wurde ein wiederholtes Problem, das wieder zu mir kam immer. In meinem Fall war das Projekt ein Telefon, auf einem 8051-Familie Prozessor, und hatte ich völlig ausgereizt das ROM (Code) -Speicher. Es kam immer wieder zu mir zu kommen, weil das Management neue Funktionen gehalten anfordert, so dass jede neue Funktion wurde ein zweistufiger Prozess. 1) Optimieren alte Sachen Raum 2) Implementieren Sie die neue Funktion zu machen, den Raum mit bis ich gerade gemacht.

Es gibt zwei Ansätze zur Optimierung. Taktische und strategische. Tactical Optimierungen sparen ein paar Bytes zu einer Zeit mit einer Mikro-Optimierung Idee. Ich glaube, Sie strategische Optimierungen benötigen, die ein radikales Umdenken zu verwickeln, wie Sie Dinge tun.

Etwas, das ich für mich erinnere gearbeitet und könnte für Sie arbeiten;

Schauen Sie sich die Essenz dessen, was Ihr Code hat einige wirklich starke und flexible primitive Operationen herauszudestillieren zu tun und zu versuchen. Dann bauen Sie Ihren Top-Level-Code, so dass es nichts niedriges Niveau tut überhaupt außer Anruf auf dem Primitiven. Im Idealfall einen Tisch basierten Ansatz verwenden, Ihre Tabelle enthält Sachen wie; Eingangszustand, Ereignis, Ausgangszustand, Primitiven .... Mit anderen Worten, wenn ein Ereignis eintritt, eine Zelle in der Tabelle nachschlagen für dieses Ereignis im aktuellen Zustand. Diese Zelle sagt Ihnen, welche neuen Staat (optional) zu ändern und welche primitive (n) (falls vorhanden) auszuführen. Sie könnten für verschiedene Schichten / Subsysteme mehrere Sätze von Zuständen / events / Tabellen / Primitive müssen.

Einer der vielen Vorteile dieses Ansatzes ist, dass Sie es als den Aufbau einer benutzerdefinierten Sprache für Ihr spezielles Problem denken kann, in dem man sehr effizient (dh mit minimalen zusätzlichen Code) neue Funktionen erstellen, indem einfach die Tabelle zu ändern.

Leider bin ich Monate zu spät und Sie wahrscheinlich nicht die Zeit sowieso etwas dieser Rest zu tun haben. Für alles, was ich weiß, dass du schon einen ähnlichen Ansatz mit! Aber meine Antwort könnte jemanden anderes, einen Tag helfen, wer weiß.

In der gerädert-out-Abteilung sollte, können Sie auch einen Teil des Codes komprimiert und nur einen Teil zu halten, die aktiv zu einem bestimmten Zeitpunkt dekomprimiert verwendet wird. Ich habe eine harte Zeit zu glauben, dass der Code für das Komprimieren / Dekomprimieren System erforderlich wäre klein genug, um ein Teil des winzigen Speicher des 8051 zu diesem lohnenswert zu machen, aber wirkte Wunder auf etwas größeren Systemen hat.

Ein weiterer Ansatz ist auf ein Byte-Code-Format oder die Art von tabellengesteuerten Code zu drehen, dass einiger Zustand Werkzeugmaschinen-Ausgang - mit einer Maschine verstehen, was Ihre Anwendung tut und eine völlig unverständliche Implementierung zu erzeugen kann ein große sein Art und Weise Raum zu sparen:)

Schließlich, wenn der Code tatsächlich in C kompiliert wird, würde ich mit einer Reihe von verschiedenen Optionen Kompilieren vorschlagen, um zu sehen, was passiert. Auch Ich schrieb ein Stück auf kompakte C-Codierung für den ESC im Jahr 2001 das ist immer noch ziemlich aktuell. , dass der Text für andere Tricks für kleine Maschinen See.

1) Wenn möglich, speichern Sie Ihre Variablen in IDaten nicht in xdata
2) Schauen Sie sich Ihre Jmp Aussagen - nutzen sjmp und AJmp

Ich nehme an, Sie wissen, dass es nicht passt, weil Sie / entsprochen schrieb und bekam die „out of memory“ -Fehler. :) Es scheint, die Antworten richten Sie Ihre Frage ziemlich genau; kurze Codebeispiele zu bekommen.

Ich würde jedoch ein paar zusätzliche Gedanken empfehlen;

  1. Stellen Sie sicher, dass der gesamte Code ist wirklich Code-Coverage-Test - verwendet? Ein nicht verwendet Unter ist ein großer Gewinn - das ist ein harter Schritt - wenn Sie sind das Original Autor, kann es einfacher sein, - (na ja, vielleicht):)
  2. Stellen Sie sicher, das Niveau der „Überprüfung“ und Initialisierung - wir manchmal haben eine Tendenz, übereifrig zu sein in die Versicherung wir initialisiert Variablen / Speicher und sicher genug zu Recht, wie oft haben wir durch sie gebissen. Nicht sagen, dies nicht tun initialisieren (DUH), aber wenn wir tun ein Speicher verschieben, das Ziel nicht Notwendigkeit zum ersten zero'd werden - diese verzahnt mit

    1 -

  3. Evaluierungs- die neuen Funktionen - kann ein bestehende Unter verbessert werden wird zur Deckung beide Funktionen oder vielleicht ein vorhandenes Feature ersetzt?
  4. Break up big-Code, wenn ein Stück der e Code kann speichern Erstellen einen neuen wenig Code.

oder vielleicht gibt es ein Argument für die Hardware-Version 2.0 auf dem Tisch jetzt ...:)

Bezug

Neben den bereits erwähnten (mehr oder weniger) offensichtliche Optimierungen, ist hier ein wirklich seltsam (und fast unmöglich zu erreichen) ein: Wiederverwendung-Code. Und mit Wiederverwendung von Code mir nicht die normale Wiederverwendung bedeutet, sondern a) Wiederverwendung des Code als Daten oder b) Code als anderer Code wiederverwenden. Vielleicht können Sie eine lut (oder was auch immer statische Daten) erstellen, dass sie durch die asm hex Opcodes vertreten können (hier Sie harvard vs Von-Neumann-Architektur suchen).

Der andere würde Code wiederverwenden, indem Code eine andere Bedeutung zu geben, wenn Sie es anders behandeln. Hier ist ein Beispiel deutlich zu machen, was ich meine. Wenn der Bytes für Ihren Code wie folgt aussehen: AABCCCDDEEFFGGHH an der Adresse X, wobei jeder Buchstabe für einen Opcode steht, stellen Sie sich jetzt auf X + 1 springen würden. Vielleicht bekommen Sie eine ganz andere Funktionalität, wo der nun durch Leerzeichen getrennt Bytes die neuen OP-Codes bilden: ABC CCD DE EF GH.

Aber Vorsicht: Dies ist nicht nur heikel ist (vielleicht ist es unmöglich) zu erreichen, aber es ist ein Schrecken zu halten. Also, wenn Sie nicht ein Demo-Code (oder etwas ähnlich exotische), würde ich empfehlen, die bereits anderen genannten Möglichkeiten zu nutzen mem zu speichern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top