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
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
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.
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.
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.
"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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.