Hallo,
IDE: AtmelStudio 7.0.1931 (Optimierung steht auf -Os)
MCU: ATXMega128A1U mit ext. SDRAM
Ich habe mir ein paar Routinen (Write/Read Byte/Word/DWord/Block, Copy
Block, ...) in Inline Assembler geschrieben, um auf den externen
Speicher zugreifen zu können. Eine dieser Funktionen macht allerdings
Probleme.
Funktion:
Mit dieser Funktion kann ich einen Speicherbereich initialisieren. An
sich läuft die Funktion. Wenn allerdings der Offset zufällig die gleiche
Größe wie die Länge hat, optimiert der Compiler etwas zu viel - trotz
dem volatile.
Beispiel-Listing OK: (seg=0x80, off=0x0010, val=0x11, len=0x000f)
Komplette Funktionen schreibt man besser in echtem Assembler. Das ist
DEUTLICH einfacher, angenehmer und der kein C-Compiler der Welt pfuscht
rein. Es gibt da eine sehr einfache, über sichtloiche App-Note zum
Thema.
doc42055
Der T. schrieb:> IDE: AtmelStudio 7.0.1931 (Optimierung steht auf -Os)
Interessiert nicht. :) Wenn schon, würde die Compilerversion
interessieren.
> Speicher zugreifen zu können. Eine dieser Funktionen macht allerdings> Probleme.
Mit anderen Worten: dein Inline-Assembler-Code ist nicht korrekt
constrained.
> Wie kann ich den Compiler zwingen hier gefälligst nicht zu optimieren?
Es ist die Aufgabe des Compilers, Code zu optimieren. Deinen
Inline-Assembler-Code selbst kann er natürlich dabei nicht anfassen, nur
die Vor- und Nachbereitung. Die constraints dienen dazu, dass du ihm
mitteilst, an welchen Stellen er was wie hinterlegen muss.
Soviel zur Vorrede. :-) Jetzt muss ich aber auch erstmal gucken, was du
da genau vergessen haben könntest …
Probier doch mal, die Länge als "+d" zu constrainen.
Korrekterweise müsstest du wohl auch den Offset als "+z" deklarieren,
denn durch das Z+ änderst du ja den Z-Pointer innerhalb des Codes.
Ich bin übrigens nicht wirklich davon überzeugt, dass man das nicht auch
gleich in C schreiben könnte.
Jörg W. schrieb:> Probier doch mal, die Länge als "+d" zu constrainen.>> Korrekterweise müsstest du wohl auch den Offset als "+z" deklarieren,> denn durch das Z+ änderst du ja den Z-Pointer innerhalb des Codes.
Der Compiler mag das "+" nicht..?
1
: "r" (val),
2
"r" (seg),
3
"z" (off),
4
"+d" (len),
5
"I" (_SFR_IO_ADDR(RAMPZ))
Dieser meckert dann mit dem Fehler: "input operand constraint contains
'+'"
Dann musst du ihn wohl bei den output operands angeben (also nach dem
ersten Doppelpunkt).
Allerdings ändert sich dann leider die Nummerierung. Nummerierte
Operanden sind aber eh bäh, besser sind benannte Operanden. Also ein
[foo] for das Constraint, und du kannst statt %0 %[foo] schreiben.
Jörg W. schrieb:> Dann musst du ihn wohl bei den output operands angeben (also nach dem> ersten Doppelpunkt).>> Allerdings ändert sich dann leider die Nummerierung. Nummerierte> Operanden sind aber eh bäh, besser sind benannte Operanden. Also ein> [foo] for das Constraint, und du kannst statt %0 %[foo] schreiben.
Das habe ich auch gerade ausprobiert - Pustekuchen!
Der Compiler optimiert hier ebenfalls.. :-(
Das Listing sieht fast genauso wie der FAIL oben aus.
Der T. schrieb:> Wie kann ich den Compiler zwingen hier gefälligst nicht zu optimieren?
Das ist nicht der richtige Ansatz. Der richtige Ansatz ist, korrekten
Code zu schreiben, z.B. so:
off und len werden verändert -> Müssen also zu den Outputs wie Jörg
bereits schrieb.
Speicher wird verändert -> "memory" muss zu den Clobbers.
avr-gcc geht davon aus, dass in RAMP* immer 0 steht -> Der Inhalt von
RAMPZ braucht nicht gemerkt zu werden, und am Ende kann RAMPZ auf 0
gesetzt werden -> Kürzerer Code.
Am Anfang des s-Files wird __RAMPZ__ zur I/O-Adresse von RAMPZ definiert
-> Weniger Operanden.
Die 16-Bit Operationen können in einem 16-Bit Befehl abgehandelt werden
-> Kürzerer Code.
Der zu wartende asm-Code kann weiter verkürzt werden, indem der
Vergleich von len aus dem asm herausgezogen wird. Falls len zur
Compilezeit bekannt ist, entfällt der Vergleich komplett.
stdbool.h (C99) definiert true und false.
Danke Johann für deinen Betrag.
Assembler nutze ich zu wenig, so dass ich zu wenig in der Materie drin
stecke. Ich programmiere fast ausschließlich in Hochsprache.
Ich werde mir dies näher ansehen und auch meine älteren Routinen ggf.
Überarbeiten. Vielen Dank für deine Unterstützung. :-)