Forum: Compiler & IDEs C-Variablen in Assembler ansprechen


von Carsten Lenz (Gast)


Lesenswert?

Hallo allerseits,
ich möchte im Assemblercode einer externen Datei (.S) Variablen, die im
C-Sourcecode deklariert sind, verwenden. In meinem Fall handelt es sich
um eine ISR , die in Assembler geschrieben ist.
Wie müssen die Variablen in C und Assembler deklariert werden, damit
ein Zugriff in beiden Programmierebenen erfolgen kann ?

Danke schon mal an die freundlichen Tippgeber,
Carsten

von Rufus T. Firefly (Gast)


Lesenswert?

Die Variable muss im C-Modul global definiert werden - sie darf also
weder eine automatische Variable in einer Funktion noch eine statische
Variable sein.
Üblicherweise wird C-Symbolen ein Unterstrich vorangesetzt, unter dem
so gebildeten Namen müssten diese dann aus Assembler ansprechbar sein:


C-Sourcefile:

  int MeineVariable;

Assembler:

  ldd r20,_MeineVariable



PS: Vermeide nach Möglichkeit Doppelpostings

von Jörg Wunsch (Gast)


Lesenswert?

Kleine Korrektur: das Voranstellen von Unterstrichen ist heutzutage
weniger üblich.  In der Historie rührte das daher, dass der
PDP-11-Assembler die Namen der Register (r0 bis r6 alias sp, pc) als
ganz normale Namen geführt hat und sie daher nicht von externen
Symbolen trennen konnte.  Da nun diese Namen aber auch gültige
C-Identifier sind, hat der C-Compiler jedem Identifier einen
Unterstrich vorangestellt, sodass nie ein Konflikt mit einem
Registernamen entstehen konnte.

Heutzutage wird der Konflikt typischerweise anders aufgelöst.  Der
GNU-Assembler für i386 benutzt bspw. ein % als Symbol für
Registernamen (%eax usw.), damit kann man das globale Symbol eax immer
vom Register %eax unterscheiden.

Beim AVR ist anhand des Opcodes bereits eindeutig ermittelbar, ob der
Operand ein Register sein kann oder nicht, der GNU-Assembler
akzeptiert dabei auch reine Zahlen für einen Registernamen (also r0
und 0 sind dasselbe).

Extern definierte globale Symbole müssen nicht zwingend deklariert
werden im Assemblercode (unbekannte Namen werden beim Auftreten im
Assembler immer erstmal als "external undefined" behandelt), aber es
ist guter Stil, sie zu deklarieren:

.extern foo

Wenn man im Assemblerprogram ein globales Symbol definieren will, tut
man das mit .global:

.global foo
foo: ...

Damit kann es dann von C aus zugegriffen werden -- die typmäßig dazu
passende C-Deklaration muss man sich natürlich selbst schreiben.

von Rufus T. Firefly (Gast)


Lesenswert?

Jörg kennt den gcc für AVR besser als irgendwer sonst, sein Tip kommt so
gewissermaßen "from the horse's mouth".
Ich arbeite mit anderen C-Compilern für andere Prozessoren - und bei
denen ist die Sache mit dem Unterstrich nach wie vor üblich. gcc ist
halt schon immer was besonderes gewesen.

von Carsten Lenz (Gast)


Lesenswert?

Schönen Dank, wie so oft fehlt oft nur ein zündender Gedanke.
Mit meinem Verständnis vom GCC habe ich versucht die Variable in C als
global static oder extern zu deklarieren.
Allgemein empfinde ich die Assembler Einbindung im GCC als recht
aufwändig, da ja gerade bei Mikrocontrollern häufig ein paar
Assemblerbefehle naheliegen. Ich könnte mir vorstellen, eine direkte
Einbindung eines Assembler Abschnittes mit z.B. .asm ... .endasm unter
Verwendung der in C deklarierten Variablen würde das Assembler Handling
vereinfachen.

von Rufus T. Firefly (Gast)


Lesenswert?

"global static" - was jetzt? Du musst Dich schon entscheiden.

Schreib' einfach in ein C-Sourcefile außerhalb einer Funktion

  int MeineVariable;

Mehr musst Du nicht tun. Damit ist das Symbol MeineVariable auf
Linkerebene definiert, um es in einem Assemblermodul ansprechen zu
können, muss dem Assemblermodul mitgeteilt werden, daß das eine externe
Variable ist.
Wie das geht, hat Jörg ja schon beschrieben:

  .extern MeineVariable

Um aus einem anderen C-Sourcefile auf diese Variable zugreifen zu
können, musst Du in dieses Sourcefile oder besser in die zum ersten
Sourcefile gehörende Headerdatei folgendes schreiben:

  extern int _MeineVariable;



Bei (mindestens einigen) anderen Compilern als gcc heisst das Symbol
dann _MeineVariable, aber auch das hat Jörg bereits geklärt.

von Jörg Wunsch (Gast)


Lesenswert?

Außerdem: den inline-Assmbler hast du dir angeguckt?

Ich empfinde ihn aber bis auf wenige Ausnahmen (Dinge wie »asm
volatile("nop"::)« zum Beispiel) als zu unübersichtlich und tendiere
eher dazu, separate Assemblerquelldateien zu nutzen.

Allerdings braucht man das alles sowieso erst im dritten Schritt.
(Erster Schritt: Prototyp alles in C, zweiter Schritt: Analyse der
Problemstellen, dritter Schritt: Assembler für als Problem erkannte
Punkte, bei denen man den Compiler nicht zu gescheitem Code überreden
konnte.)

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.