Forum: Compiler & IDEs C-Header mit as nutzen


von Marcus G. (carbon9)


Lesenswert?

Hallo,

mein Problem ist, dass ich mehrere umfassende C-Header Dateien habe und 
die darin liegenden #define Anweisungen im Assembler brauche. Hat jemand 
Ahnung, wie ich C-Header Dateien mit dem GNU Assembler nutzen kann? Oder 
kennt jemand ein Script, welches die C-Header in der Form #define xxx 
yyy in .equ xxx, yyy umwandeln kann?

Danke schon im voraus.

Marcus

von Kindergärtner (Gast)


Lesenswert?

Mit "gcc -x assembler-with-cpp blub.S -c -o blub.o" assemblisieren, und 
du kannst den Preprocessor genau wie in C verwenden:

#include "test.h"
#define NUM 7

ldi r16, NUM

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Marcus Gottschalk schrieb:
> Hat jemand Ahnung, wie ich C-Header Dateien mit dem GNU Assembler nutzen
> kann?

Indem du alle nur für C relevanten Dinge (wie typedefs, structs usw.)
durch
1
#ifndef __ASSEMBLER__
2
3
...
4
5
#endif /* !__ASSEMBLER__ */

für den Assembler nicht mehr sichtbar machst.  Die #defines lässt du
natürlich sichtbar, und da der Präprozessor sie vor dem Aufruf des
Assemblers bereits ersetzt, brauchst du auch keine .equ oder sowas
draus zu machen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Kindergärtner schrieb:
> Mit "gcc -x assembler-with-cpp blub.S -c -o blub.o" assemblisieren,

Das "-x assembler-with-cpp" ist überflüssig, denn für S-Dateien (dito 
für sx-Dateien) ist dies die Voreinstellung analog zu "-x c" für 
c-Dateien.

von Marc P. (marcvonwindscooting)


Lesenswert?

Das funktioniert nicht, wie hier beschrieben, denn im C-Header findet 
man nicht

#define NUM 7

** SONDERN: **

enum {
  NUM=7,
};

Ich kenne das Problem auch und hab mir deshalb mal ein Script 
geschrieben das aus einem simple Text-Format sowohl .h als auch .s macht 
- "ahnlich wie Markus vorschl"agt.

wie w"ar's mit Perl?
Hier ein Vorschlag, der immerhin aus enums im obigen Stil (dez und hex) 
die entsprechenden equ macht...

#!/usr/bin/perl -w
#
while(<>) {
        if (m/(\w+)\s*=\s*((0x|0X)?\d+)/x) {
                print ".equ $1, $2\n";
        }
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Marc P. schrieb:
> Das funktioniert nicht, wie hier beschrieben, denn im C-Header findet
> man nicht
>
> #define NUM 7

Wieso weißt du das besser als der TE?  Der schrieb ausdrücklich, dass
in seinem fraglichen Header da #defines drin stehen.

Wenn das bei deinem Header anders ist, ja, dann funktioniert diese
Methode natürlich nicht.

Dein Mini-Script wiederum funktioniert nicht bei enums wie:
1
enum foo {
2
  BAR = 42,
3
  MUMBLE,
4
  STAR,
5
};

von Marc P. (marcvonwindscooting)


Lesenswert?

Sorry, aber man darf ja vielleicht noch darauf hinweisen, dass #define 
mehr misbraucht als gebraucht wird. Eben gerade in diesem Fall. Es sei 
denn, der gute Marcus weiss schon vorher, dass in keinem der 
umfangreichen Header was drin ist wie:

#define LDR 13        // Pin vom Photowiderstand
#define R7 12000      // 12 kiloOhm
#define MOV 0815      // type des Varistors

#define XLAT 666

Dann wird er n"amlich vermutlich nicht so tolle Fehlermeldungen 
bekommen, hahahahahaha!

Und .equ ist mitnichten eine Text-Ersetzung. Mit .equ kann man Symbole 
definieren, sogar .global. Ist schon was anderes.

Und 'mein Miniscript hab ich gestern als "Ubung gemacht. F"ur das was 
Marcus NICHT wollte reichts. Und ich hab's absichtlich nicht f"ur 
#define gemacht, da muss er schon selber Hand anlegen. Was aber nicht so 
schwer sein sollte...

von lol (Gast)


Lesenswert?

Marc P. schrieb:
> #define LDR 13        // Pin vom Photowiderstand
> #define R7 12000      // 12 kiloOhm
> #define MOV 0815      // type des Varistors
>
> #define XLAT 666

Wer solche defines in ernsthaften Programmen anlegt sollte nicht 
programmieren...

von Rolf Magnus (Gast)


Lesenswert?

Marc P. schrieb:
> #define LDR 13        // Pin vom Photowiderstand
> #define R7 12000      // 12 kiloOhm
> #define MOV 0815      // type des Varistors

Für keins davon wäre ein enum irgendwie sinnvoll.
Und da du hier schon Haare spaltest:

Marc P. schrieb:
> Dann wird er n"amlich vermutlich nicht so tolle Fehlermeldungen
> bekommen, hahahahahaha!

Die bekommt er bei dem hier:

Marc P. schrieb:
> #define MOV 0815      // type des Varistors

auch schon in C, wenn er es benutzt. 0815 ist keine gültige 
Integer-Konstante.

von lol (Gast)


Lesenswert?

Rolf Magnus schrieb:
> 0815 ist keine gültige
> Integer-Konstante.

gültig schon, aber halt oktal.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

lol schrieb:
> Rolf Magnus schrieb:
>> 0815 ist keine gültige
>> Integer-Konstante.
>
> gültig schon, aber halt oktal.

Bitte geh zurück auf "Los!".

von Marc P. (marcvonwindscooting)


Lesenswert?

> Wer solche defines in ernsthaften Programmen anlegt sollte nicht
> programmieren...

> Für keins davon wäre ein enum irgendwie sinnvoll.

Hmm? Weshalb?
Muss jeder C-Programmierer nun jeden erdenklichen Assembler kennen?
Also ich leg solche Konstanten an, ich sollt's vermutlich besser lassen 
und mir 'nen neuen Job suchen.

> Bitte zur"uck auf LOS.
Worum geht's?
Es geht darum, dass meiner bescheidenen Meinung nach im Assembler-Code 
keine Header von C-Code (oder von irgendeiner anderen 
Programmiersprache) was verloren haben. Das sind ganz andere 
Namenskonventionen, Schl"usselworte, usw. . Der Thread-Starter hatte 
schon die Option eines Scripts im Sinn (zumindest als Alternative) und 
in die Richtung kam vor meinem Beitrag Null. Vielleicht ahnte er schon, 
was f"ur ein Rumgehure die Geschichte mit dem Pr"aprozessor w"are...

Darf ich noch sagen, warum ich die Konvertierung mittels Script als 
einzig sinnvolle Veriante ansehe?

1. ein Pr"afix kann eingef"ugt werden kann vor jedem Bezeichner, der 
importiert wird. (.equ C_VAR, 7)
2. es eben AUCH mit enums gehen kann...
3. es sogar mit #defines und enums gehen kann!

Wenn ihr nicht selbst w"usstet, wass f"ur'n Sch*** #defines oder das 
Pr"aprozessorkonzept sind, w"urded ihr euch gar nicht so aufregen!!
Die Griechen haben denjenigen, der entdeckt hatte, dass es irrationale 
Zahlen geben muss, einfach auf hohe See "uber Bord geworfen um das 
Problem aus der Welt zu schaffen.

Ja, ihr habt doch recht. Das Problem mit dem Namen existiert gar nicht 
und #defines sind v"ollig unbedenklich und nebenwirklungsfrei. Und ihr 
tut gut daran sie weiterzuverbreiten.
Als n"achstes wird 'const', 'restrict' verboten, alles neumodische 
Quatsch und man darf wieder alles in alles andere casten (per Pointer) 
und die C-Welt ist wieder in Ordnung (und auf dem Niveau von K&R, 70er 
Jahre).
OMG AKA WTF

von Simon K. (simon) Benutzerseite


Lesenswert?

Beruhig dich. Gerade die Menschen, die sich grad an einer Diskussion mit 
dir beteiligen sind die "GCC Elite" hier im Forum ;-)

Wenn wir schon dabei sind, nervt mich dieses Anführungsstriche als 
Umlaut. :-P

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Marc P. schrieb:

> Also ich leg solche Konstanten an, ich sollt's vermutlich besser lassen
> und mir 'nen neuen Job suchen.

Wenn du das für dich machst, ist das deine Sache.  Denk aber immer
dran, dass du auch mit deiner Variante einige Randbedingungen
beachten musst: wenn du immer alles als enums abbilden willst und
dann den Anspruch hast, per Script daraus das Assembler-Äquivalent
zu zimmern, dann musst du entweder alle enum-Werte auscodieren
(was eigentlich dem Sinn eines enums, Werte einfach aufzählen zu
können und den tatsächlichen Wert dann dem Compiler zu überlassen,
ein wenig entgegen steht), oder aber dein Script muss deutlich
intelligenter werden.  Auch dürfen in C mehrere enum-Werte auf einer
Zeile stehen.

Nich jede x-beliebige Konstante lässt sich sinnvoll als enum
darstellen (auch, wenn es bei vielen sinnvoller als ein #define ist).
Sowas beispielsweise ist mittelmäßig sinnlos:
1
enum bits {
2
   BIT0 = 1,
3
   BIT1 = 2,
4
   BIT2 = 4,
5
   BIT3 = 8,
6
};
7
8
enum bits bitvar = BIT0 | BIT3;

Es gibt hier keinen Vorteil mehr gegenüber einem #define, denn der
Debugger kann für "bitvar" nicht mehr sagen, welchen enum-Wert die
Variable gerade hat, da es für den aktuellen Wert einfach keine
Zuordnung gibt.

>> Bitte zur"uck auf LOS.
> Worum geht's?

Bezüglich dieser Bemerkung darum, dass 0815 keine gültige
Integer-Konstante in C ist.  Eben auch nicht oktal.

> Es geht darum, dass meiner bescheidenen Meinung nach im Assembler-Code
> keine Header von C-Code (oder von irgendeiner anderen
> Programmiersprache) was verloren haben.

Das ist deine Meinung, und die sei dir unbenommen.

Du darfst aber akzeptieren, dass andere Leute eine andere Meinung
dafür haben.  Beispielsweise sind sämtliche io-Header-Dateien für
den AVR so gestaltet, dass man ihre darin enthaltenen Werte auch
im Assemblercode benutzen kann.  Dies zu tun, hat durchaus Sinn,
auch und gerade im Zusammenhang mit dem GCC (in dessen Forum wir
uns ja befinden), da der GCC seit Jahr und Tag in der Lage war,
Assemblerdateien automatisch als Argument so mit zu verarbeiten,
dass sie zuvor durch den C-Präprozessor geschickt worden sind.

Der Ansatz mit dem Script ist ein anderer, aber er ist nicht per se
besser oder schlechter als der mit den #defines.  Er ist eben nur
anders.  Jeder hat seine eigenen Vor- und Nachteile.

> Wenn ihr nicht selbst w"usstet, wass f"ur'n Sch*** #defines oder das
> Pr"aprozessorkonzept sind, w"urded ihr euch gar nicht so aufregen!!

#defines und der Präprozessor haben ganz gewiss ihre Tücken, keine
Frage.  Sie haben aber auch Stärken, und zumindest in C kann man auf
sie nicht sinnvoll komplett verzichten.  (In C++ mit seinen echten
Konstanten sieht das ein wenig anders aus, dort sind enums auch echte
Typen geworden statt nur eines Aliases für "int".)

Wie so oft im Leben ist es die sinnvolle Verwendung bestimmter
Features, auf die man achten sollte, statt der prinzipiellen
Verteufelung bestimmter Konstrukte.  Nicht umsonst hat Donald Knuth
seinerzeit mal einen Artikel geschrieben, der da hieß: “Structured
Programming with go to Statements”.

von Marcus G. (carbon9)


Lesenswert?

Wow also echt Respekt, wie sich der Thread entwickelt hat. Kam in 
letzter Zeit leider nicht dazu ihn zu verfolgen.

Kindergärtner schrieb:
> Mit "gcc -x assembler-with-cpp blub.S -c -o blub.o" assemblisieren, und
> du kannst den Preprocessor genau wie in C verwenden

Das funktioniert erstmal wirklich hervorragend. Danke für diese Hilfe :)

Der Vorwand von Marc P. ist natürlich berechtigt.
Marc P. schrieb:
> Das funktioniert nicht, wie hier beschrieben, denn im C-Header findet
> man nicht
>
> #define NUM 7
>
> ** SONDERN: **
>
> enum {
>   NUM=7,
> };

Ich habe jedoch das Gefühl, da diese Strukturen in keiner Funktion 
aufgerufen werden, werden diese auch nicht in Code übersetzt und sind 
damit gar nicht vorhanden.

Vielleicht hätte ich hinzufügen sollen, dass es um einen AT32UC3A1512 
Prozessor und dessen libs von Atmel geht. Diese sind jedoch nicht für 
Assembler verfügbar. Der Prozessor hat siwiso ein paar Bugs:
Bei breq verzweigt bei gesetztem Z-Flag im Simulator. Die Hardware 
bewirkt das Gegenteil wobei bei brne und gesetztem z-Flag verzweigt 
wird. Aber gut dies gehöhrt nicht zum Thread

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.