mikrocontroller.net

Forum: Compiler & IDEs C-Variablen in Assembler ansprechen


Autor: Carsten Lenz (Gast)
Datum:

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

Autor: Rufus T. Firefly (Gast)
Datum:

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

Autor: Jörg Wunsch (Gast)
Datum:

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

Autor: Rufus T. Firefly (Gast)
Datum:

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

Autor: Carsten Lenz (Gast)
Datum:

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

Autor: Rufus T. Firefly (Gast)
Datum:

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

Autor: Jörg Wunsch (Gast)
Datum:

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

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.