www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Makros in C und ASM nutzen


Autor: Paul S. (paul_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Arnold (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: 123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
__GNUC__
__STDC__

oder:
__ASSEMBLER__

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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'
#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.

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.

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Christian H. (netzwanze) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
#define FOO  123

beispiel.c:
#include "defs.h"

int blah()
{
        return FOO;
}

asm.S:
#include "defs.h"

asm_blah:
        mov     r0, #FOO
        ret


Und wenn mir das jemand noch immer nicht glaubt:
$ cpp asm.S
# 1 "asm.S"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "asm.S"
# 1 "defs.h" 1
# 2 "asm.S" 2

asm_blah:
        mov r0, #123
        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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Erich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Paul S. (paul_s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.