mikrocontroller.net

Forum: Compiler & IDEs C Variablen in ASM-Code


Autor: Andreas Auer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Ich hab folgendes Problem. Ich hab eine globale Variable in meinem
C-Code. Nun möchte ich die Interrupt Service Routine in ASM schreiben,
da mir C da zuviele PUSH und POP's reinhaut.
Ich mach also mein ASM File und definiere dort mit
.global SIG_OUTPUT_COMPARE1B

meinen Beginn der Routine. Soweit klappt ja alles noch problemlos. Ich
muss aber aus diesem ASM Code auf eine globale C Variable zugreifen.
Geht das, oder muss ich mir da irgendwas anderes einfallen lasen??

mfg
Andreas

--
Andreas Auer               aauer1 (at) sbox.tugraz.at
Student of Telematics      http://home.pages.at/aauer1
Graz, University of Technology

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das geht.

Autor: Andreas Auer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi.

Könntest mir vielleicht auch noch verraten wie es geht?? Ich bekomm
immer eine Fehlermeldung beim Kompilieren, da er die Variable ja nicht
finden kann.
Muss ich in der ASM Datei auch noch irgendwas definieren??

mfg
Andreas

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht beschreibst Du ja erstmal, was Du denn gemacht hast?  Meine
Kristallkugel ist leider gerade zur Reparatur...

Autor: Andreas Auer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok... ich geb hier mal ein kleines Beispielprog an, so wie meins in etwa
aussieht.

C-File:
~~~~~~~

unsigned char buffer[1024];

int main(void)
{
  // alle möglichen init's
  // Timer1 Interrupt initialisieren und starten
  // Timer1 im Output Compare Mode, wobei der Output Pin toggelt

  sei();    // global Interrupt enable

  while(1);
}

Die Interrupt Service Routine in C ist mir klar. Aber die ist für meine
Zwecke unbrauchbar, da sie zu langsam ist. Der Output Pin toggelt etwa
alle 10us.

Mein ASM File sieht vorerst nur so aus:

#include <avr/io.h>

.global SIG_OUTPUT_COMPARE1B:
  reti

Damit wollte ich nur mal sehen, ob der Compiler und Linker auch alles
richtig zusammensetzt. Hab mir das .lss File erzeugen lassen und es hat
gepasst. Bei nem entsprechenden Interrupt wird diese Funktion
aufgerufen.

Jetzt noch das was ich will:
In dem ASM File möchte ich in der ISR die globale C Variabel von oben
("unsigned char buffer[1024]") verwenden.
Und zwar brauche ich ja nur die Adresse der Variable. Danach kann ich
eh auf alle Werte zugreifen!
Ich hab auch schon folgendes  in der ISR versucht:

  ldi r16, high(buffer)

Und genau hier liegt das Problem! Ich hoffe, dass ich es jetzt
einigermaßen klar gemacht habe!

mfg
Andreas

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, man bekommt auch eine ISR in C durchaus flink, aber lassen wir
das.

> .global SIG_OUTPUT_COMPARE1B:

Das wolltest Du sicher in zwei Zeilen aufteilen, eine mit dem .global,
eine mit dem Doppelpunkt für den Label -- sonst nimmt es der Assembler
nicht.

> In dem ASM File möchte ich in der ISR die globale C Variabel von
> oben ("unsigned char buffer[1024]") verwenden.

Ja, das .global hast Du ja schon gefunden, da ist doch der Weg bis zum
.extern gar nicht mehr weit?  Die Typinformation und Größe des Arrays
ist natürlich für den Assembler bedeutungslos, die mußt Du als
Programmierer ja einhalten.  .extern ist übrigens eine Art NOP: der
Assembler nimmt alle Namen, die auftauchen und ihm nicht irgendwoher
bekannt sind, als `global undefined' an, so daß sie der Linker
auflößen muß.  .extern dokumentiert aber, daß man sich nicht einfach
irgendwas ausgedacht hat als Programmierer, sondern daß es die
Definition dieses Objekts irgendwo außerhalb gibt.

> ldi r16, high(buffer)

Fast.

  ldi r16, lo8(buffer)
  ldi r17, hi8(buffer)

Leider sind diese beiden Operatoren nicht dokumentiert. :-( (Wie auch
alle anderen Erweiterungen im Assembler, die für den AVR gemacht
worden sind.)

Der einfachste Weg ist immer noch, sich den vom Compiler generierten
Code direkt anzusehen (Quelldatei foo.c: "make foo.s", dann foo.s
ansehen), da lernt man die paar zusätzlichen Operatoren recht einfach.

Autor: Andreas Auer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Besten Dank für die Hilfe.

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.