Hallo! In meinem Projekt habe ich etwas Assembler-Code und viel C Code. In beiden Teilen gibt es Makro-Definitionen, oft für das Selbe: Assembler: #set DEVICE MB96346RxA; #set CLOCK_SPEED CPU_24MHZ_CLKP2_12MHZ C: #define PROZESSORTYP 96348 #define F_SYSTEM 24000000 // CPU-Takt in Hz Die Beispiele sind jetzt nicht perfekt, weil die Sachen nicht ganz identisch sind, aber ich wollte auch nur klarstellen, wofür das sein soll. Ich suche einen Weg, z.B. die Taktfrequenz nur einmal zu definieren, und diese Definition (per include?) sowohl in Assembler als auch in C zu benutzen. Hat das schon jemand hinbekommen? Ich hoffe auf kreative Vorschläge! Viele Grüße Paul
Der C Präprozessor verarbeitet Text und hat in Wirklichkeit von C keine Ahnung. Also kann man auch Assembler Quelltext durchjagen und so dieselben Includes verwenden. Meist wird man noch dem cpp ein "#define ASSEMBLER" (beim GNU cpp auf der Kommandozeile Option -DASSEMBLER) oder ähnlich mitgeben, dann kann man per #ifdef Teile, die nicht für den Assembler geeignet sind, ausklammern. Ruft man den Assembler über gcc auf, verwendet der automatisch den Präprozessor wenn die Dateiendung .S oder .sx (statt .s) ist.
Hallo Paul, kannstDu nicht ein #define auf ein #set machen? Also ein #define auf ein #define sozusagen? In C geht das jedenfalls. in etwa so... Assembler: #set DEVICE MB96346RxA; #set CLOCK_SPEED CPU_24MHZ_CLKP2_12MHZ C: #define PROZESSORTYP DEVICE #define F_SYSTEM CLOCK_SPEED // CPU-Takt in Hz Gruß Arnold
aber ein #ifdef C_COMPILER #define PROZESSORTYP DEVICE #define F_SYSTEM CLOCK_SPEED // CPU-Takt in Hz #else #set DEVICE MB96346RxA; #set CLOCK_SPEED CPU_24MHZ_CLKP2_12MHZ #endif wobei C_COMPILER entweder beim Aufruf des C Compiler mit vermutlich -D übergebenes Define ist. Oder der C Compiler hat ein spezielles Define, an dem man erkennen kann das es sich um diesen compiler haldelt. bzw der ASM eines.
Ich denke aber doch, das das alles am eigentlichen Kern des Problems vorbei geht. Insofern hat der TO ein schlechtes Beispiel geliefert. Er will #set CLOCK_SPEED 8000000 und #define CLOCK_SPEED 8000000 irgendwie so zusammenführen, dass der Zahlenwert nur 1-mal auftritt. AFAIK und IMHO geht das aber nicht. Mit dem C-Preprozessor ist es nicht möglich, Ersetzungen so vorzunehmen, dass sich neue Preprozessorstatements ergeben. Ob das mit dem Assembler möglich ist, hängt dann vom Assembler ab. Erwarten würde ich das aber nicht. d.h. der 'Weg'
1 | #ifdef ASSEMBLER
|
2 | #set PRE_RPOC_COMMAND #set
|
3 | #else
|
4 | #define PRE_PROC_COMMAND #define
|
5 | #endif
|
6 | |
7 | PRE_PROC_COMMAND CLOCK_SPEED 8000000 |
bei dem ja nach 'Übersetzer' einmal ein #set und das andere mal ein #define auftaucht, das wird es so nicht spielen. Wenn Assembler und C unterschiedliche Preprozessor-Direktiven zum festlegen von Makro-Substitutionen benutzen, dann bist du weg vom Fenster. Das einzige was gehen könnte: Man könnte sich den C-Preprozessor 'ausborgen', damit er sich ein Assemblerfile vorab vornimmt. Wie das aber aussehen soll, weiss ich auch noch nicht.
Dann bleibt als Alternative, solche Definitionen in einem anderen PP zu definieren (z.B. m4) und daraus die Headerdateien für C und Assembler zu generieren. Ist dafür vielleicht etwas overkill, aber eröffnet gleichzeitig noch mehr Spielereien.
Eine Möglichkeit besteht noch. Du nimmt einfach ein einzelnes C-File mit Defines. Dann noch ein Skript, welches Dir das C-File in eine passende Assembler-Syntax umbaut (suchen/ersetzen) - zum Beispiel mit "sed". Das Skript wird bei jedem Makefile-Aufruf gestartet und baut aus dem C-File ein Assembler-File. Danach wird Compiliert und Assembliert - alles aus dem gleichen Projekt-Makefile heraus.
Ich versteh euer Problem nicht… Karl heinz Buchegger schrieb: > Er will > > #set CLOCK_SPEED 8000000 > > und > > #define CLOCK_SPEED 8000000 > > > irgendwie so zusammenführen, dass der Zahlenwert nur 1-mal auftritt. Also bleibt nur das #define in der gemeinsamen Include-Datei. > d.h. der 'Weg' > #ifdef ASSEMBLER > #set PRE_RPOC_COMMAND #set > #else > #define PRE_PROC_COMMAND #define > #endif > > PRE_PROC_COMMAND CLOCK_SPEED 8000000 > > bei dem ja nach 'Übersetzer' einmal ein #set und das andere mal ein > #define auftaucht, das wird es so nicht spielen. Nein, wozu auch? Wieso muss ein #set erzeugt werden? Ich denke doch es geht nur um Konstanten. Solange der Assembler dieselbe Syntax für Konstanten wie der C-Compiler frisst (also etwa Hex-Konstanten mit 0x am Anfang, Bitshifts als (1<<BLABLA)) gibt es doch gar kein Problem.
Andreas B. schrieb: > Nein, wozu auch? Wieso muss ein #set erzeugt werden? Weil vielleicht derjenige, der den Assembler geschrieben hat, sich eingebildet hat, dass die Definition von Ersetzungen oder Konstanten dort #set abcd efgh lautet. > Solange der Assembler dieselbe Syntax für Konstanten wie der C-Compiler > frisst (also etwa Hex-Konstanten mit 0x am Anfang, Bitshifts als > (1<<BLABLA)) gibt es doch gar kein Problem. Solange. Und wenn nicht?
Karl heinz Buchegger schrieb: > Weil vielleicht derjenige, der den Assembler geschrieben hat, sich > eingebildet hat, dass die Definition von Ersetzungen oder Konstanten > dort > > #set abcd efgh > > lautet. Die Idee ist doch, den C-Präprozessor die Ersetzungen machen zu lassen. Ist doch völlig schnurz wie das im Assembler gemacht werden würde so man denn dessen Funktionen einsetzen täte. > Solange. > Und wenn nicht? Dann muss man aufpassen und kompatible Definitionen verwenden (dezimal wird der Assembler wohl mindestens können). Oder man machts halt doch kompliziert und schreibt ein Programm, das äquivalente Definitionen aus der Vorlage eines Includes erzeugt.
Andreas B. schrieb: > Karl heinz Buchegger schrieb: >> Weil vielleicht derjenige, der den Assembler geschrieben hat, sich >> eingebildet hat, dass die Definition von Ersetzungen oder Konstanten >> dort >> >> #set abcd efgh >> >> lautet. > > Die Idee ist doch, den C-Präprozessor die Ersetzungen machen zu lassen. > Ist doch völlig schnurz wie das im Assembler gemacht werden würde so man > denn dessen Funktionen einsetzen täte. Du verstehst es immer noch nicht. Die Idee ist es, ein und denselben Code so aufzubereiten, dass * die Assembler Syntax eingehalten wird * die C Snytax eingehalten wird * Alle vom Programmierer einstllbaren Konstanten trotzdem nur ein einziges mal vorkommen Die Idee ist es, ein Konfigurationsfile zu haben, welches sowohl von C als auch von Assembler aus benutzt (inkludiert) werden kann, und alle reelvanten Dinge in der jeweiligen Zielsyntax bereitstellt. Aber nur 1 File und jede Konstante soll nur 1 mal vorkommen. > Dann muss man aufpassen und kompatible Definitionen verwenden (dezimal > wird der Assembler wohl mindestens können). Es geht nicht um Zahlen und deren Darstellung. Es geht darum, zwei verschiedene Syntaxen unter einen Hut zu bringen. So wie wenn du ein und denselben Source Code so schreiben willst, dass ein C Compiler damit glücklich ist und derselbe Source Code, ohne Änderungen, auch durch einen Fortran Compiler durchgejagt werden kann und auch dort ein Programm erzeugt, das sich dann auch noch identisch verhält.
Das "Problem" könnte ja auch sein, dass der Assembler kleinen C-Präprozessor verwendet. Er kann also mit eine #ifdef nichts anfangen. Natürlich könnte man diesen dem Assembleraufruf auch vorschalten. Dieser erzeugt dann als Ausgabedatei eine für den Assembler verständliche Syntax.
Christian H. schrieb: > Das "Problem" könnte ja auch sein, dass der Assembler kleinen > C-Präprozessor verwendet. Er kann also mit eine #ifdef nichts anfangen. > Natürlich könnte man diesen dem Assembleraufruf auch vorschalten. Dieser > erzeugt dann als Ausgabedatei eine für den Assembler verständliche > Syntax. Das sagte ich ja gleich zu Beginn, man soll den Assembler Quelltext durch den C-Präprozessor jagen. Der Assembler wird nie ein #ifdef sehen. Das ist eine derart weit verbreitete Lösung, dass es der gcc, wie ich schon erwähnte, automatisch machen kann. Oder nochmal in langsam: defs.h:
1 | #define FOO 123
|
beispiel.c:
1 | #include "defs.h" |
2 | |
3 | int blah() |
4 | {
|
5 | return FOO; |
6 | }
|
asm.S:
1 | #include "defs.h" |
2 | |
3 | asm_blah: |
4 | mov r0, #FOO |
5 | ret |
Und wenn mir das jemand noch immer nicht glaubt:
1 | $ cpp asm.S |
2 | # 1 "asm.S" |
3 | # 1 "<built-in>" |
4 | # 1 "<command-line>" |
5 | # 1 "asm.S" |
6 | # 1 "defs.h" 1 |
7 | # 2 "asm.S" 2 |
8 | |
9 | asm_blah: |
10 | mov r0, #123 |
11 | ret |
Wenn der Assmbler die Zeilenmarker nicht interpretieren kann, gibts die Option -P. Dann stimmen in Fehlermeldungen die Zeilennummern aber nur für die Ausgabe des Präprozessors.
Andreas B. schrieb: > Und wenn mir das jemand noch immer nicht glaubt: Wir glauben dir das doch. Die Lösung mit dem cpp ist ja nun schon oft genug in diesem Thread gefallen. Aber gibt es auch eine Lösung, die ohne cpp auskommt?
Vielleicht sollte man sich für ein (das) Projekt einig werden, ob nun in C oder in ASM programmiert wird. Damit verschwindet dieses "Problem" ganz von alleine.
Hallo, danke für die zahlreichen Antworten. Für mich ist das Problem gelöst, viel einfacher als ich dachte. Mein Fujitsu-Assembler versteht die C-Präprozessor Makros. Ich war nur nicht auf die Idee gekommen, weil die nicht drinstanden und immer #set statt #define benutzt wurde. Es geht aber bei diesem(!) Assembler beides. Aus dem Handbuch: The #set instruction can be executed for the same macro name as many times as necessary. The difference from the #define instruction is that the #set instruction allows the macro name to be used as a variable. Warum Fujitsu im Beispielcode dann z.B. den Prozessortyp mit #set und nicht mit #define festlegt ist mir nicht ganz klar, ich habe noch nicht gehört, dass sich der Prozessortyp im Betrieb ändert... Auf jeden Fall habe ich jetzt einfach ein zusätzliches konfig.h File, in dem Prozessortyp, Frequenz und Debugmodus definiert werden, und sowohl ASM als auch C-Files includen das und benutzen den Inhalt, z.B. im ASM: #if PROZESSORTYP == 96348 #if PROZESSORVARIANTE == A #set DEVICE MB96348RxA ; <<< select device #else #set DEVICE MB96348RxB ; <<< select device #endif #endif Mehr wollte ich gar nicht. Ich bin gespannt, ob es doch noch eine geniale Lösung für Assembler gibt, die solche Direktiven nicht verstehen. Paul
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.