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:
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
@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.
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.