Hallo,
mit der Inline-ASM Geschichte bin ich noch nicht so richtig durch,
nährere mich aber dem Ziel. Nachdem ich nun festgestellt habe, daß die
gesamte (3-teilige) Operandenliste ans Ende einer Anweisungsliste kommt
und erst die Ausgabe-Operanden, angeführt durch ein ':' und getrennt mit
Komma, dann die Eingabe-Operanden und als drittes die Clobber-Liste.
Passend zu den einzelnen Operanden müssen die Constraints sein, sonst
gips Mecker vom gcc und das wird alles nix. So weit, so gut --- denkt
man....
Konkret habe ich mir wieder eine Spielwiesendatei gebaut, worin ich
einzelne Inline-Assembler Funktionen aufbaue und dran rumschraube. Bis
auf 2 Fehlermeldungen vom gcc habe ich m. W. alles soweit stehen, aber
es gibt Motze vom gcc:
qq.c: In function 'assemble':
qq.c:18: error: output operand constraint lacks '='
qq.c:9: error: output operand constraint lacks '='
qq.c:9: error: invalid lvalue in asm output 0
Dazu der gesamte Code
1 | #include <avr/io.h>
|
2 | #include <stdint.h>
|
3 |
|
4 | unsigned char x, y, z;
|
5 |
|
6 | //static inline assemble(uchar8_t var_x, uchar8_t var_y, uchar8_t var_z)
|
7 | static inline void assemble(void)
|
8 | {
|
9 | asm volatile
|
10 | ( // Zeile 10
|
11 | "add r29,%0\n\t"
|
12 | "add r30,%1\n\t"
|
13 | "add r31,%2\n\t"
|
14 | "lpm \n\t"
|
15 | "out %3,r0\n\t"
|
16 | : "I" (PORTB) // Zeile 16
|
17 | : "r" (x), "r" (y), "r" (z) // Zeile 17
|
18 | ); // Zeile 18
|
19 | }
|
20 |
|
21 | int main(void)
|
22 | {
|
23 | x = 42;
|
24 | y = 50;
|
25 | z = 84;
|
26 |
|
27 | //assemble(x, y, z);
|
28 | assemble();
|
29 | }
|
Zwei Möglichkeiten wären da, einmal die Parameter an die
assemble()-Funktion per Parameterübergabe zu übergeben oder als globale
Variablen, so wie es jetzt oben steht.
Was ich nicht verstehe ist
ersma, was sollen mir die Fehlermeldungen bzgl. "output operand
constraint lacks '='" und "invalid lvalue in asm output 0" sagen?
Zweitma verstehe ich nicht, warum in diversen Dokus geschrieben steht,
daß es heißen muß
1 | : "I" _SFR_IO_ADDR(PORTB)"
|
in einer anderen, fast genau der gleichen Doku heißt
also ohne "_SFR_IO_ADDR(...)". Lass ich das Makro weg, habe ich eine
Fehlermeldung weniger (mit: qq.c:18: error: invalid lvalue in asm
statement).
Und dann noch, warum die constraints der Eingabeoperanden "r" sein
müssen, und nicht wie in anderen Beispielen zu sehen war, einfach nur
"0" z.b.
Wie wäre die Parameterübergabe von 3 nur-lesen-Zeichen (uchar8) richtig?
Alternativ habe ich auch selbiges wie oben mit einer separaten
Assembler-Datei versucht (qq.S), allerdings bekomme ich hier keine
Parameter in die Assemblerfunktion rein. In irgendeiner Doku stand, das
das bei globalen Variablen, die in einem C-File stehen, so gemacht wird:
1 | #include <avr/io.h>
|
2 | #define __ASEMBLER__
|
3 |
|
4 | .extern x
|
5 | .extern y
|
6 | .extern z
|
7 |
|
8 |
|
9 | .section .text
|
10 |
|
11 | .global schrauben
|
12 | .func schrauben
|
13 |
|
14 | ... blabla das zeugs von oben
|
15 |
|
16 | .endfunc
|
17 | .end
|
Die Fehlermeldungen hierzu lautet, daß die Variablen x, y und z nicht
bekannt sind, obwohl die im C-File global und aus meiner C-Erfahrung
raus auch für externe Funktionen sichtbar sind. Definiert sind die als
'static volatile unsigned char'.
So, hoffe auf hilfreiche Reaktoren und geh schonmal ins Bett, is ja
schon wieder sooooo spät und muß morgen auch wieder "anne Schippe".