mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik [Inline ASM] - Iterieren eines Arrays


Autor: Jakob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo µC-Board.

Ich stehe hier vor einem Problem, welches ich nicht gelöst bekomme. Auch 
nachdem ich die AVRlibc Doku und das Tutorium auf dieser Seite 
durchgearbeitet habe verstehe ich es einfach nicht.

Ich möchte einem Inline ASM-Codesegment die Adresse eines C-Arrays 
übergeben, sodass diese innerhalb des Z-Pointers steht.
Die Iteration durch das Array schaffe ich mit Sicherheit selbst. Ich 
scheitere lediglich an der Adress-Übergabe.

Könnte mir hier vielleicht jemand eine Beispiel-Operandenliste zur 
Verfügung stellen?

Mit freundlichem Gruß,
Jakob

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint8_t Array[10];
...

asm volatile (
  // Inkrement Z
  "adiw  %0, 1   \n\t"
  // auf R30 zugreifen
  "cpi  %A0, 42  \n\t"
  // auf R31 zugreifen
  "cpi  %B0, 42  \n\t"
  :            // kein Output
  :"z" (Array) // Array in Z als Input
);

Autor: Jorge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe zwar keine Erfahrung damit beim AVR aber vom Vorgehen her ist 
es am einfachsten, wenn man eine "C" Funktion schreibt und sich 
anschaut, was der Compiler daraus macht also den erzeugten Assemblertext 
anguckt. Dort steht mit Sicherheit die Lösung.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jorge wrote:
> Ich habe zwar keine Erfahrung damit beim AVR aber vom Vorgehen her ist
> es am einfachsten, wenn man eine "C" Funktion schreibt und sich
> anschaut, was der Compiler daraus macht also den erzeugten Assemblertext
> anguckt. Dort steht mit Sicherheit die Lösung.

Das funktioniert nicht in Bezug auf Inline Assembler.

Autor: Jakob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dank für die schnelle Antwort.

Ich bin zwar recht fit in ASM, doch dieser Code macht mich etwas 
stutzig:
uint8_t Array[10];
...

asm volatile (
  // Inkrement Z
  "adiw  %0, 1   \n\t"
  // auf R30 zugreifen
  "cpi  %A0, 42  \n\t"
  // auf R31 zugreifen
  "cpi  %B0, 42  \n\t"
  :            // kein Output
  :"z" (Array) // Array in Z als Input
);

"cpi" ist mir als Mnemonic für "Compare with Immediate" also eine 
Branch-Instruction bekannt. wieso ist das jetzt ein Zugriff auf dieses 
Register?
Ich müsste eher mit "ld" bzw. "st" arbeiten, um auf die Werte 
zuzugreifen, oder sehe ich das total falsch?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist nur ein Beispiel, wie man dann die beiden Register einzeln 
anspricht. Das Entscheidende ist hier das "%A0". Als Befehl (cpi) habe 
ich nur was x-beliebiges genommen.

Autor: Jakob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach so..

Also sehe ich das richtig, dass dieser Code die Adresse des Arrays in 
den Z-Pointer (R30:R31) lädt?

Wenn das der Fall ist kann ich ja ohne Probleme "ld" und "st" verwenden.

Vielen Dank für diese Antwort und die Erklärungen.

Mit freundlichem Gruß,

Jakob

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jakob wrote:

> Also sehe ich das richtig, dass dieser Code die Adresse des Arrays in
> den Z-Pointer (R30:R31) lädt?

Genauer:
Der Input-Constraint '"z" (Array)' veranlasst den Compiler, dafür zu 
sorgen, dass vor Ausführung des Inline-Asm die Adresse von Array im 
Z-Pointer steht.

Du solltest dich unbedingt näher mit den Constraints beschäftigen. Die 
sind schließlich das A und O des Inline-Assemblers.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...oder keinen inline-Assembler benutzen sondern separate Assembler-
Quelldateien.  Das ist meist einfacher und übersichtlicher.

Inline asm ist ,,nur für Eggsberden'': für sie ist er gut, mächtig
und sinnvoll.  Besonders den Autoren der Systembibliothek gibt er
Mittel in die Hand, Sonderfunktionalitäten zu erreichen, ohne dabei
dem normalen Optimierungsfluss des Compilers mehr als notwendig im
Weg herum zu liegen.  Auf der Gegenseite muss man sich aber eben
(über diese constraints) auch ein wenig damit vertraut machen, wie
der Compiler intern so arbeitet, denn nur dadurch ist diese nahtlose
Integration erst möglich.

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.