Forum: Compiler & IDEs assembler-with-cpp


von Fabian Braun (Gast)


Lesenswert?

hallo zusammen

habe bei meinem projekt nebst den c files einige routinnen in assembler
geschrieben. wenn ich sie mit der endung .S benenne und im makefile
angebe funktioniert das compilen wunderbar.
aber anscheinend sollte man ja mittels des aufrufs "-x
assembler-with-cpp" auch .asm dateiendungen geben können und die files
muss man nicht mehr alle im makefile separat angeben...stimmt das?!?
jedoch gibt mir der compile mit dieser compilierart tausende von
fehlern. er beschwert sich über ausdrücke in c files die alle korrekt
geschrieben sind.
was könnte da los sein?!?
ah genau...noch was...wieso kann ich in meinen assemlberfiles
präprozessor definitionen (#define dummy 0) die ich in c files angebe
nicht benutzten?!?

hoffe jemand weiss mir zu helfen :-)

merci!

gruss fab

von Jörg Wunsch (Gast)


Lesenswert?

(Wäre wohl passender im GCC-Forum.)

> aber anscheinend sollte man ja mittels des aufrufs "-x
> assembler-with-cpp" auch .asm dateiendungen geben können und die
> files muss man nicht mehr alle im makefile separat angeben...stimmt
> das?!?

Jein.  Ja, man sollte die Dinger damit auch .asm benennen können --
obwohl ich das selbst noch nie ausprobiert habe, es gibt für mich
keinen Grund, nicht .S zu benutzen.

Nein, es ändert sich dadurch weiter nichts, als daß Du die Dateien mit
einem für den Compiler ansonsten unbekannten Suffix (die er dem Linker
vorwerfen würde) zwangsweise durch cpp und as schickst.  Insofern ist
mir der zweite Teil Deiner Annahme unverständlich und vermutlich auch
falsch: wie sonst als durch separate Angabe im Makefile sollte der
Compiler noch erfahren, welche Dateien er assemblieren lassen soll?

> ah genau...noch was...wieso kann ich in meinen assemlberfiles
> präprozessor definitionen (#define dummy 0) die ich in c files
> angebe nicht benutzten?

Die Frage läßt sich so allgemein nicht beantworten.  Wenn Du die
Variante Assembler + Präprozessor benutzt, kannst Du sehr wohl mit
#define Makros arbeiten (wofür sollte der cpp sonst gut sein?), aber
Du kannst natürlich keine C-Konstrukte in den Makros verwenden.
#define dummy 0 sollte natürlich tun, wenn das bei Dir nicht
funktioniert, mußt Du konkret werden mit einem Beispiel.

von Fabian Braun (Gast)


Lesenswert?

>(Wäre wohl passender im GCC-Forum.)
ist's ja oder nicht?!?

das erste problem ist mir jetzt klar...DANKE!!

das zweite noch nicht ganz :-S
aber was ich jetzt gerade gemerkt habe...dass er ja
zuerst die .asm files assembliert und nachher das c-zeux macht.
wenn das so ist und der compiler zuerst nur die .asm files "anschaut"
dann kann er ja nicht wissen was in denn c-header-files defniniert ist
oder etwa schon?!?


>(wofür sollte der cpp sonst gut sein?),
was für ein cpp?!? hat das etwas mit dem "-x assembler-with-cpp" zu
tun?!? sorry aber ich schnalls jetzt grad überhaupt nicht :-S

danke für deine hilfe

gruss fab

von Jörg Wunsch (Gast)


Lesenswert?

>> (Wäre wohl passender im GCC-Forum.)

> ist's ja oder nicht?!?

Hat Andreas offenbar hierher verschoben jetzt.

> wenn das so ist und der compiler zuerst nur die .asm files
> "anschaut" dann kann er ja nicht wissen was in denn c-header-files
> defniniert ist oder etwa schon?!?

Mir dünkt, Du machst hier irgendwas grundfalsch, ich weiß aber
natürlich nicht was.  Du solltest Dir wohl mal die Zusammenhänge,
welcher Teil des Compilers was anstellt, ein bißchen verdeutlichen,
statt nur im Dunkeln zu stochern.

Alle Dateien werden grundsätzlich unabhängig voneinander übersetzt,
egal ob Assembler, C, FORTRAN, Ada, ... :)  Headerdateien werden vom
C-Präprozessor reingezogen, das Ergebnis wird dann dem nachfolgenden
Compiler (oder Assembler eben) übergeben.

Außerdem solltest Du wohl wissen, daß der Assembler alle symbolischen
Konstanten, die auftauchen und nicht zuvor definiert waren, als extern
annimmt, d. h. deren Auflösung überläßt er dem Linker (bzw. der
beklagt sich, wenn er sie nicht auflösen kann).

>> (wofür sollte der cpp sonst gut sein?),

> was für ein cpp?!?

Der C-Präprozessor.  Über den reden wir ja schließlich.  Er behandelt
all die Dinge im Programmtext, die mit # anfangen bzw. die Ersetzung
der entsprechenden #define Makros.

> hat das etwas mit dem "-x assembler-with-cpp" zu tun?

Ja, aus ebendiesem Grunde heißt diese Option so: das Programm wird
zuerst durch den C-Präprozessor gezogen und danach dem Assembler
geschickt.  Das entspricht dem Standardfall für Dateien, die dem
Compiler als .S benannt werden.

von Fabian Braun (Gast)


Lesenswert?

hallo jörg

nein andreas hat's nicht verschoben...bin mir ziemlich sicher dass
ichs im richtigen forum gepostet habe...ja tut ja nichts zur sache!

OK den rest hab ich mal verstanden...präprozessor war für mich bis
jetzt sehr fremd...werd mich mal schlauer machen in einem buch anstatt
dich di ganze zeit mit fragen zu nerven!

tausen dank für deine hilfe!

gruss fab

von Fabian Braun (Gast)


Lesenswert?

eins hab ich noch...wo muss ich im makefile genau das "-x
assembler-with-cpp" hineinschreiben?!? bei ASFLAGS = ... ist es schon
drin oder muss es bei CFLAGS = ... rein?!? also wenn ichs nur bei
ASFLAGS drin lasse und im .asm file präprozessormakros verwende, gibts
jede menge fehler. wenn ichs bei CFLAGS reintu, dann gibts in allen c
files jede menge fehler.
könnte jemand vielleicht mal ein beispiel posten...wär nicht übel!

gruss fab

von Jörg Wunsch (Gast)


Lesenswert?

Es gehört zu den ASFLAGS.

Wenn Du da Fehler bekommst, solltest Du die besser analysieren, statt
nur rumzuraten...  Hmm, oder wie wär's damit: Du hast Dein Makefile
so
verbogen, daß Du ASFLAGS gar nicht mehr benutzt?  Dann kannst Du
natürlich da reinschreiben, was Du willst...  Am Ende, siehe ganz
oben, warum willst Du die Dateien denn überhaupt zwanghaft auf .asm
enden lassen, wenn's doch mit .S schon funktioniert hat?  Ich denke
die ganze Zeit, Du hast eigentlich ein ganz anderes Verständnisproblem
hier, nur was das genau ist, sagst Du uns nicht.

von Fabian Braun (Gast)


Lesenswert?

hmm...naja...ich versuch glaubs mal mein problem neu zu definieren:
bitte alles oben mal vergessen!!!

hallo erstmal:->

hier mal ein beispiel:

code für nlcd.S
===============

#define _ASSEMBLER_ 1
#define __SFR_OFFSET 0

#include <avr/io.h>
#include <avr/signal.h>

#define  dummy      0

  .global  test
test:

  mov  R0, dummy

ret

=== nlcd.S --- ENDE ====

=== nlcd.h =====

#define  dummy      0

void test(void);

==== nlcd.h ENDE =====


==== mp3_player.c ====

#include <avr/io.h>
#include <avr/signal.h>
#include "nlcd.h"

void main(void)
{
  test();
  while (1);
}

==== ENDE ==========

so compilen ... funktioniert wunderbar!
aber wenn ich jetzt in nlcd.S das #define dummy 0 rausnehme, dann
sollte es doch auch funktionieren, weil dummy in nlcd.h definiert
ist...jedoch sagt der compiler "constant value required", also soviel
wie "ich weiss nicht was dummy heisst".
ich will einfach z.b. im nlcd.h sachen definieren und diese sozusagen
in nlcd.S gebrauchen. oder ist dies überhaupt nicht möglich?!??

merci für die hilfe

gruss fab

von Jörg Wunsch (Gast)


Lesenswert?

>  mov R0, dummy

Ich glaube, das ist nicht wirklich das, was Du hier tun willst. ;-)

Der Präprozessor macht daraus:

  mov R0, 0

Laut Instruction manual führt `mov' eine Register-Register
Kopieroperation durch, d. h. Du kopierst Register #0 nach Register #0,
man könnte das auch `nop' nennen, etwas aufwendig geschrieben.  Ich
vermute ganz stark, daß Du das gar nicht wolltest...

Was wolltest Du denn damit wirklich tun?  Register R0 mit einem
Direktoperanden laden?

  ldi r0, dummy

Oder Register R0 mit dem Inhalt der Speicherzelle 0 laden (ist zwar
sinnlos, weil Speicherzelle 0 wieder auf Register 0 zeigt, aber das
lassen wir mal beiseite)?

  lds r0, dummy

Allerdings gebe ich zu, daß Assembler auch nicht meine Stärke ist, ich
muß dafür ebenfalls ins Manual gucken.  Ich lasse das lieber den
Compiler erledigen, der kann das in aller Regel sowieso besser als
ich.

> aber wenn ich jetzt in nlcd.S das #define dummy 0 rausnehme, dann
> sollte es doch auch funktionieren, weil dummy in nlcd.h definiert
> ist...

Nein, Dein nlcd.S besitzt doch kein #include "nlcd.h".  Woher soll
der
Compiler (genauer: der Präprozessor) denn erraten, daß er dieses
Headerfile dort ebenfalls einbinden soll?  Das mußt Du ihm schon
sagen.

> ich will einfach z.b. im nlcd.h sachen definieren und diese
> sozusagen in nlcd.S gebrauchen. oder ist dies überhaupt nicht
> möglich?

Es ist schon, aber so, wie Du das derzeit anstellst, hat das alles
keinen Sinn.

Am ehesten hat es Sinn, daß man tatsächlich reine Konstanten (so wie
z. B. auch in <avr/io.h>) in derartigen Headerfiles deklariert.
Typische C-Deklarationen à la

extern int foo;

sind völlig sinnlos, da natürlich der Assembler damit nichts anfangen
kann.  Wenn Du das ganz paranoid machen willst, kannst Du natürlich
sowas machen:

#if defined _ASSEMBLER_ (*)
.extrn foo
#else
/* für C-Programme */
extern int foo;
#endif

aber eigentlich kannst Du das auch auf

#if !defined _ASSEMBLER_
extern int foo
#endif

verkürzen.  Andernfalls, wenn Deine Headerdatei nur extern irgendwas
Deklarationen enthält, kannst Du dann gleich darauf verzichten, sie in
den Assemblercode einzubinden.  Es hätte nur Sinn, wenn sie außerdem
vielleicht noch sowas enthält:

#define FOOBAR 42

...und Du die Konstante FOOBAR sowohl von C als auch Assemblerdateien
benutzen willst.  Im Assemblercode kannst Du gleich schreiben

  lds r24, foo
  lds r25, foo+1

damit r24/r25 den int-Wert der (globalen) Variablen `foo' geladen
bekommen.  Hat natürlich nur für lds/sts Sinn, denn nur die gehen auf
den Speicher.  Was auch gehen müßte ist sowas (aber s. o., Assembler
ist nicht meine Stärke):

  ldi r28, lo8(foo)
  ldi r29, hi8(foo)
  ld  r24, Y
  ldd r25, Y+1

Denke an die register usage guidelines (stehen in der avr-libc FAQ),
welche Register für Parameterübergabe dienen, welche Du frei belegen
darfst usw. usf.

(*) _ASSEMBLER_ sollst Du nicht selbst definieren, der
Compilertreiber erledigt das für Dich, wenn er Assemblerquellen mit
dem cpp bearbeiten läßt.

von Fabian Braun (Gast)


Lesenswert?

hallo jörg

so...jetzt ist "der zwanzger gfallä" --> ich schnalls jetzt!!
ist mir jetzt sonnenklar, dass man ja noch die headerfiles includen
muss...klar sonst weiss er ja nicht welches dass er nehmen soll :-S und
das mit dem #if !defined _ASSEMBLER_ ist auch klar da er sonst im
asemlbermodus bei c-ausdrücken ausruft und diese jedock beim compilen
trotzdem copilet!!!! ich schnalls ... welch ein wunder :-)...sorry dass
du dir die finger wegen mir so wund schreiben musstest!

>mov R0, 0
ja weiss schon dass das keine sinn macht...war ein bisschen in eile und
wollte einfach noch ein beispiel posten und nicht gerade mein 200
zeiligen quellcode :-S...aber hast recht hätte auch ein bisschen
überlegen könen bei der auswahl des beispiels :-S

>Denke an die register usage guidelines (stehen in der avr-libc FAQ),
welche Register für Parameterübergabe dienen, welche Du frei belegen
darfst usw. usf.
ja sehr wohl! schon studiert und völlig kapiert! ja langsam kommt der
assembler...hab für ein nokia3310-lcd und für den vs1011 mp3 dekoder
assemblerroutinen geschrieben und in c datei eingebunden...funktioniert
wunderbar und vorallem super schnell die sache ;-)

dankedankedankedanke für deine hilfe und geduld!!

gruss fab

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.