Forum: Mikrocontroller und Digitale Elektronik SDCC Assembler und bedingte Assemblierung


von Wilhelm F. (Gast)


Lesenswert?

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?

von Wilhelm F. (Gast)


Lesenswert?

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).

von sdas (Gast)


Lesenswert?

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

von Wilhelm F. (Gast)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

@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

von er mi (Gast)


Lesenswert?

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.

von Wilhelm F. (Gast)


Lesenswert?

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. ;-)

von Wilhelm F. (Gast)


Lesenswert?

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.

von Stefan++ (Gast)


Lesenswert?

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

von Wilhelm F. (Gast)


Lesenswert?

Und? Was spart mir die Sache?

Assemblierzeit? Heutzutage völlig unwichtig.

von Ralf (Gast)


Lesenswert?

@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

von Peter D. (peda)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Wilhelm F. (Gast)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

Freut mich, wenn wir helfen konnten :) Falls wir uns mal begegnen zahlen 
wir uns gegenseitig n Bier.

Ralf

von Wilhelm F. (Gast)


Lesenswert?

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.

von Ralf (Gast)


Lesenswert?

> 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
Noch kein Account? Hier anmelden.