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
1 | uint8_t Array[10]; |
2 | ...
|
3 | |
4 | asm volatile ( |
5 | // Inkrement Z
|
6 | "adiw %0, 1 \n\t" |
7 | // auf R30 zugreifen
|
8 | "cpi %A0, 42 \n\t" |
9 | // auf R31 zugreifen
|
10 | "cpi %B0, 42 \n\t" |
11 | : // kein Output |
12 | :"z" (Array) // Array in Z als Input |
13 | );
|
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.
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.
Dank für die schnelle Antwort. Ich bin zwar recht fit in ASM, doch dieser Code macht mich etwas stutzig:
1 | uint8_t Array[10]; |
2 | ...
|
3 | |
4 | asm volatile ( |
5 | // Inkrement Z
|
6 | "adiw %0, 1 \n\t" |
7 | // auf R30 zugreifen
|
8 | "cpi %A0, 42 \n\t" |
9 | // auf R31 zugreifen
|
10 | "cpi %B0, 42 \n\t" |
11 | : // kein Output |
12 | :"z" (Array) // Array in Z als Input |
13 | );
|
"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?
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.
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
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.
...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.
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.