Schon wieder SDCC, aber ich gebe nicht auf. Im Augenblick habe ich ein Projekt in viele kleine ASM-Files gesplittet, die aber über ein Command-File (Batch) immer alle assembliert und gelinkt werden sollen. Auch wenn per bedingter Assemblierung mit Defines keine Daten und kein Code drinne sind. Ich möchte die bedingte Assemblierung, wo in einer Definitionsdatei alle Switches gesetzt werden, und ich aus Codeersparnis in einem Projekt bei Erstellung Code sparen muß. Toter Code, den ich nicht brauche, und das muß ich manuell in den Definitionen setzen, soll nicht mit assembliert und gelinkt werden, der Assembler hat auch da keine Optimierung. Sonst bekommt man für ein Programm, was 1,8kB hat, die ganzen 5kB, die man entwickelte, und einiges nicht braucht, assembliert und gelinkt. Es soll aber in 2kB ROM passen. So include ich also in jedes File ein Definitionsfile namens defines.inc. In dieses Definitionsfile werden der Einfachheit halber auch schon die Registerdefinitionen des 80C515 mit includet. Das sollte aber kein Problem sein. Nur beim Scrollen im Listing. Da steht z.B. drin: BIN_BCD = OFF Oder: BIN_BCD = ON Für ein skalierbares mächtiges Zahlenumwandlungstool, was beliebig große Binärzahlen in BCD wandelt. Wobei zuvor schon OFF = 0 und ON = 1 definiert wurde. Konkret: In einem der vielen ASM-Files namens arithmetik.asm steht bei einem Segment eine Definition drin, z.B. .if BIN_BCD. Dann assemblieren. Ich habe es auch probiert mit Ausdrücken wie: .if BIN_BCD & ON In der ASxxxx Cross Assembler Documentation steht noch schön, daß Definitionen, die mit .if .else .endif aúsgewertet werden können, bis zu 10 Leveln schachtelbar sind. Also sowas wie #define SYMBOL in C. Es geht nicht. Das Scheißding macht nur Mist. Bis zum Linker komme ich nicht mal, der Assembler alleine macht mir schon Relocation Error und Phase Error. Obwohl die Definitionsdatei Includet ist. Warum?
So, ich habs jetzt gelöst, es brauchte aber einen Tag, um dahinter zu kommen, was Assembler und Linker nicht mögen, und wo die Doku zu komplexeren Konstruktionen über Files verteilt nicht weiter eingeht. Ich möchte die Dinge auch niemandem vorenthalten. Es könnte ja, wenn auch Monate oder Jahre später, oder überhaupt, mal jemand danach suchen. Deshalb schreibe ich noch mal was dazu: Man darf bei verschachtelten Define-Symbolen nicht nur mit .if abfragen, um dann eine neue Definition zu erstellen, sondern muß auch immer den .else Fall mit definieren. Dann gehts. Beispiel:
1 | OFF = 0 |
2 | ON = 1 |
3 | |
4 | ARITHMETIK_USED = OFF |
5 | |
6 | .if ARITHMETIK_USED |
7 | BCD_TO_BIN_USED = OFF |
8 | BIN_TO_BCD_USED = ON |
9 | SUBB_BIN = ON |
10 | .else ; ab hier immer alles OFF, aber definiert |
11 | BCD_TO_BIN_USED = OFF |
12 | BIN_TO_BCD_USED = OFF |
13 | SUBB_BIN = OFF |
14 | .endif |
Ohne den .else Fall streikt das Ding nur noch, wenn das übergeordnete Symbol ARITHMETIK_USED nicht wahr ist. Der .else Fall bläht die Definitionen ziemlich auf, nämlich auf das Doppelte. Das stört etwas die Übersichtlichkeit in komplexeren Projekten. Aber man muß es nur einmal richtig machen. Für ein Projekt brauche ich also ein dem Projekt zugeordnetes Define-File, und natürlich ebenso ein projektbezogenes Main-File, alle anderen Files mit Funktionen können immer bleiben, wie sie sind. Es werden immer alle .asm-Files assembliert, und auf diese Weise toter Code manuell aussortiert. Das ist bei mir aktuell nötig, da mein Board nur 2kB (eine Page) Programmspeicher RAM zum Testen hat. Mit einem printf() in C wäre der schon halb voll. Da verwende ich zu Jumps und Calls am 8051 die Platz sparenden ACALL- und AJMP-Befehle, die ein Byte kürzer sind als LCALL und LJMP. Das macht in einem Programm schon mal 200 Byte Unterschied. Auf diese Weise möchte ich immer alle asm-Files in einem Source-Ordner haben, für ganz verschiedene Projekte, und die werden immer alle assembliert. Was assembliert wird, bestimmen die Defines. Eine bessere Idee hatte ich noch nicht, aber so läuft wenigstens mal alles vollautomatisch. Erstellung des Hex-Files mit Maschinencode über einen Button-Click per Command-File (Batch).
Ich kenne das Scheißding nicht, aber ein solches Verhalten erscheint mir sehr ungewöhnlich. Kann es sein, dass im Fehlerfall einfach bestimmte Definitionen gefehlt haben? Ich hätte es einmal so versucht:
1 | OFF = 0 |
2 | ON = 1 |
3 | |
4 | ; Defaultwerte fuer alle Definitionen |
5 | BCD_TO_BIN_USED = OFF |
6 | BIN_TO_BCD_USED = OFF |
7 | SUBB_BIN = OFF |
8 | |
9 | ARITHMETIK_USED = OFF |
10 | |
11 | .if ARITHMETIK_USED |
12 | BIN_TO_BCD_USED = ON |
13 | SUBB_BIN = ON |
14 | .endif |
sdas schrieb: > Kann es sein, dass im Fehlerfall einfach bestimmte > Definitionen gefehlt haben? Kann sein, daß es so auch geht. Weniger Definitionszeilen hat man damit aber auch nicht. Also: Ich wollte im Grunde einfach ein höher priorisiertes Symbol auswerten, um danach niedriger priorisierte Symbole zu definieren, und zu verwenden. Ich werde es wohl so lassen, wie ich es erfunden habe.
@Wilhelm: > Also sowas wie #define SYMBOL in C. Wenn mich nicht alles täuscht fällt aber ein C-Preprocessor auch auf die Nase, wenn das Symbol in einer #if-Abfrage nicht definiert ist. Laut diesem Handbuch: http://shop-pdp.kent.edu/ashtml/asmlnk.htm sollte aber .ifdef funktionieren. Vielleicht wäre das ein Ansatzpunkt. Ralf
Wenn die abhängigen Symbole später referenziert werden und diese Referenzen ihrerseits nicht auch wieder bedingt sind, müssen sie natürlich in allen if-else Zweigen definiert sein.
Ralf schrieb: > sollte aber .ifdef funktionieren. Vielleicht wäre das ein Ansatzpunkt. .ifdef gibts beim sdas8051 nicht. Leider. Sonst wäre es einfacher. er mi schrieb: > Wenn die abhängigen Symbole später referenziert > werden und diese Referenzen ihrerseits nicht > auch wieder bedingt sind, müssen sie natürlich in allen > if-else Zweigen definiert sein. Das hättest du mir mal früher schreiben sollen. ;-)
Ralf schrieb: > Laut diesem Handbuch: > http://shop-pdp.kent.edu/ashtml/asmlnk.htm > sollte aber .ifdef funktionieren. Vielleicht wäre das ein Ansatzpunkt. > > Ralf Das ist ja genau mein Manual. Wo hast du da .ifdef gefunden? Denn ich fand da keinen Suchtreffer.
Hallo, jetzt wo alles so schön läuft doch noch eine blöde Frage !!! Warum machst du aus deinen vielen Assembler-Files (Modulen) nicht einfach eine Bibliothek ??? Jeder Linker (dieser auch ?) linkt nur die notwendigen Module der Bibliothek. Du sparst dir deine "defines.inc" und bekommst das kleinst mögliche Programm von selbst
Und? Was spart mir die Sache? Assemblierzeit? Heutzutage völlig unwichtig.
@Wilhelm: > .ifdef gibts beim sdas8051 nicht. Leider. Sonst wäre es einfacher. > Das ist ja genau mein Manual. Was denn nun? ;) > Wo hast du da .ifdef gefunden? Denn ich fand da keinen Suchtreffer. Ich finde es unter Kap. 1.4.31, Seite 1-36 >> Warum machst du aus deinen vielen Assembler-Files (Modulen) nicht >> einfach eine Bibliothek ??? > Und? Was spart mir die Sache? > Assemblierzeit? Heutzutage völlig unwichtig. Nein, es spart dir möglicherweise die Defines, etc. Aus einer Bibliothek wird, wie Stefan++ schon schrieb nur das genommen, was gebraucht wird. Wenn du also eine Lib mit den Funktionen Fa, Fb und Fc hast und in deinem Programm aber nur die Funktion Fa brauchst (= aufrufst) wird auch nur diese in den Code eingebunden. Je nachdem, wie eine Lib zu generieren ist musst du aber im Sourcecode definieren, wo eine Funktion anfängt und aufhört, sonst musst du evtl. für jede Funktion ein eigenes Sourcefile erstellen. Prinzipiell würde ich aber sagen, dass die Verwendung von Libs vorteilhaft ist. Dein o.g. Problem dürfte damit rausfallen. Ralf
Wilhelm Ferkes schrieb: > Und? Was spart mir die Sache? Codegröße. Wird ein Funktion aufgerufen, wird sie automatisch aus der Lib hinzugelinkt. Ansonsten nicht. Du sparst Dir also das ganze Gerödel mit den Defines, die machen den Code nur noch undurchsichtiger. In der C-Welt wird es nur so gemacht. Peter
Wilhelm Ferkes schrieb: > .ifdef gibts beim sdas8051 nicht. Leider. Sonst wäre es einfacher. Oftmals benutzen die Assembler, die zu eine C-Compiler gehören, auch den C-Preprozessor. D.h. versuch mal #define und #ifdef. Peter
Ralf schrieb: > @Wilhelm: >> .ifdef gibts beim sdas8051 nicht. Leider. Sonst wäre es einfacher. >> Das ist ja genau mein Manual. > Was denn nun? ;) >> Wo hast du da .ifdef gefunden? Denn ich fand da keinen Suchtreffer. > Ich finde es unter Kap. 1.4.31, Seite 1-36 Uuuuups, da ist mir aber was passiert! Ich hab mir ja gestern noch den Link angeschaut, und sah, daß es auf den ersten Blick das Manual ist, was ich vor 2 Monaten mit dem neuesten SDCC herunter lud. Aber nur auf den ersten Blick. Die Kapitel gehen aus meiner Version von vor 2 Monaten nur bis 1.4.19, dann kommt 1.5. Das ist mysteriös, ich schaute mir den Link jetzt gerade noch mal genauer an. Das ist ja ein Ding, Version August 2012. Also wirklich brandneu. Es hat sich mal eine Menge getan, ein richtiger großer Sprung! Die habe ich natürlich nicht, es gibt tatsächlich in kurzer Zeit schon wieder ein Update, das meine Version von vor 2 Monaten jetzt erheblich erweitert. Vielen vielen Dank dafür, Ralf!!! Unter Umständen muß ich dann jetzt auch das SDCC-Paket noch mal neu downloaden, weil auch Assembler und Linker darauf hin upgedatet sein könnten. Die Registerdefinitionen für 80C515 waren auch so ein Kreuz, die mußte ich komplett überarbeiten. Dort habe ich allerdings keine Hoffnung, daß man daran gearbeitet hat. 80C515 ist immerhin eine alte Kamelle, die lange nicht mehr gebaut wird, und 80C517 mußte ich mir selbst komplett neu bauen. Libraries für die speziellen Funktionen z.B. der MDU und Multiple Datapointer gibt es im SDCC-Paket nicht. Die brauchte ich wiederum in C. Das gibt auch noch eine Menge Anpassungsarbeit z.B. in den Mathe-Libraries und STDLIB-Funktionen wie z.B. memcpy(). Aber es ist eine Herausforderung für mich. Peter Dannegger schrieb: > Wilhelm Ferkes schrieb: >> Und? Was spart mir die Sache? > Codegröße. Ja eben, darum dreht sich doch das Thema, daß ich manuell mit Defines toten Code ausschalte. Es funktioniert auch prächtig, wie ich es seit gestern habe, nur nicht vollautomatisch durch Assembler und Linker selbst. Von den einfachen Freeware-Tools erwarte ich auch keinen Handstand auf einem Arm. Es war immer Setup-Arbeit, anders als bei teueren kommerziellen Ready-To-Use-Tools wie Keil. > Wilhelm Ferkes schrieb: >> .ifdef gibts beim sdas8051 nicht. Leider. Sonst wäre es einfacher. > Oftmals benutzen die Assembler, die zu eine C-Compiler gehören, auch den > C-Preprozessor. > D.h. versuch mal #define und #ifdef. Siehe Ralf, der gerade ein neueres Manual für mich fand. Aber Jungs, Ralf, danke, auch Peter, der hier immer was gutes hat, alle Aspekte helfen irgendwie weiter. Von früher bin ich es gewohnt, nicht täglich nach Tool-Updates zu suchen. Meinen ASM51 gab es noch auf Buchdiskette (8051-Handbücher zu den Siemens-Derivaten vom Otmar Feger Verlag), und man arbeitete Jahre lang ohne neuere Versionen. Das war früher so. Otmar Feger bot mir den ASM51 drei Jahre später mit ein paar Erweiterungen an, meinte aber, es sei nicht so wichtig. Der hatte dann nur die Register der A-Versionen von 80515 und 80517 mit integriert. Ich kaufte etwa 1998 bei ihm ein paar Leerplatinen für das Opto-Net-Mini mit SAB80C517A, und ein paar DCF77-Bausätze bzw. Leerplatinen. Und hatte ihn einmal persönlich an der Strippe. Das war auch ganz nett. Also, es ist schon gut, daß ich meine Frage hier stellte. Es hat was bewirkt.
Freut mich, wenn wir helfen konnten :) Falls wir uns mal begegnen zahlen wir uns gegenseitig n Bier. Ralf
Ralf schrieb: > Freut mich, wenn wir helfen konnten :) Falls wir uns mal begegnen zahlen > wir uns gegenseitig n Bier. > > Ralf Für dich gibts auch zwei Biere. Schönes Wochenende, wünsche ich.
> Für dich gibts auch zwei Biere. Davon würd ich gleich eins an Peter abtreten :) > Schönes Wochenende, wünsche ich. Ebenso. Ralf
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.