PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : wieso erzeugt der Inline-Assembler falschen Code?



cl
25.03.2007, 23:59
Hallo,

ich habe ein Problem mit dem Inline-Assembler vom AVR-GCC 4.0.1. Ohne Optimierung übersetzt läuft alles einwandfrei und der Code funktioniert. Wenn man die Optimierung jedoch einschaltet, dann erzeugt er Unsinn. Ich habe das Problem auf folgendes reduzieren können:


{
uint8_t colcntr8;
uint8_t end8 = 253;

asm volatile(
"cp %0, %1" "\n\t" : : "r" (colcntr8), "r" (end8) );
}

Der AVR-GCC erzeugt (Target-MCU ATmega128) ohne Optimierung:
cp r25, r24
Mit Optimierung erzeugt er jedoch:
cp r24, r24
Also für meine Zwecke nicht so sinnvoll.

Was kann/soll ich tun, damit der Code auch mit Optimierung sinnvoll ist?

Danke im Voraus
- cl

SprinterSB
26.03.2007, 08:37
Also für meine Zwecke nicht so sinnvoll.

Dein C-Code ist auch nicht so sinnig ;-)

Du verwendest colcntr8 als nicht-initialisierten in-parameter. Es kann also *irgendeinen* Wert haben. Warum also nicht gen gleichen wie end8?

cl
26.03.2007, 12:20
naja das clr am Anfang habe ich auch wegelimiert. :) Scheint den Compiler aber auch nicht wirklich zu jucken, denn wenn man jedoch die Variable colcntr8 auf 0 initialisiert, dann geht der Code und es kommt was richtiges raus! Auch mit Optimierung! Mal wieder ein Beispiel dafür, dass der C-Compiler den Inhalt der Inline-Assembler Teile nicht kennt!

Ob das jedoch sinnvoll ist, was er erzeugt darf man IMHO auch in Frage stellen ...

Vielen Dank für die Hilfe
- cl

SprinterSB
26.03.2007, 13:54
Wenn du auf C-Ebene mit 0 initialisiert funktioniert es also wie von mir erklärt. Wenn es nicht initialisiert ist, dann ist der Code nicht sinnvoll und damit das, was GCC erzeugt, im Rahmen dessen also voll in Ordnung.

GCC *kann* nicht wissen, was im Inline-Assembler abgeht. Wie auch? Soll er ne syntaktische und semantische Analyse des Schnippsels machen, dann ne Kontrollfluss- und Datenanalyse und wer weiß was noch? Diesen riesigen(!) Aufwand nur, um zu raten, was man mit nicht-korrektem C-Code vielleicht meinen könnte?

Wenn du die 0 in einem Register brauchst kannst zu __zero_reg__ verwenden. Das enthält immer die 0.

Oder du machst ein CLR auf ein Register. In diesem Falle ist das Register OUT-Operand und wahrscheinlich early clobber.