Bad expression

Gast #5601
Lesenswert?

Hallo!

Hab folgende C-Funktion geschrieben mit eingebettetem Assembler-Code, 
welche nichts weiter machen soll als einen gewissen Delay.

...void delay05(void)
...{
...  asm volatile
...  (
...    // =============================
...    //    delay loop generator
...    //     8333333 cycles:
...    // -----------------------------
...    // delaying 8333325 cycles:
297    "          ldi  R17, #37h"  "\n\t"
298    "WGLOOP0:  ldi  R18, #D6h"  "\n\t"
299    "WGLOOP1:  ldi  R19, #EBh"  "\n\t"
...    "WGLOOP2:  dec  R19"  "\n\t"
...    "          brne WGLOOP2"  "\n\t"
...    "          dec  R18"  "\n\t"
...    "          brne WGLOOP1"  "\n\t"
...    "          dec  R17"  "\n\t"
...    "          brne WGLOOP0"  "\n\t"
...    // -----------------------------
...    // delaying 6 cycles:
306    "          ldi  R17, #02h"  "\n\t"
...    "WGLOOP3:  dec  R17"  "\n\t"
...    "          brne WGLOOP3"  "\n\t"
...    // -----------------------------
...    // delaying 2 cycles:
...    "          nop"    "\n\t"
...    "          nop"    "\n\t"
...    // =============================
...    :
...    :
...  );
...}

Ich bekomme jedoch folgende Fehler vom Compiler:

C:\TEMP\ccXbaaaa.s: Assembler messages:
C:\TEMP\ccXbaaaa.s:297: Error: Bad expression
C:\TEMP\ccXbaaaa.s:297: Error: garbage at end of line
C:\TEMP\ccXbaaaa.s:298: Error: Bad expression
C:\TEMP\ccXbaaaa.s:298: Error: garbage at end of line
C:\TEMP\ccXbaaaa.s:299: Error: Bad expression
C:\TEMP\ccXbaaaa.s:299: Error: garbage at end of line
C:\TEMP\ccXbaaaa.s:306: Error: Bad expression
C:\TEMP\ccXbaaaa.s:306: Error: garbage at end of line

die Zeilen hab ich mit Zahlen markiert!

Was ist daran falsch und wie muss es richtig heißen?
Gast #5603
Lesenswert?

supi funzt!

#D6h hatte ich genommen weil ich das von der Asm-Programmierung mit dem 
80C517 kannte. Urpsürnglich stand aber &D6 dort, aus dem 
AVRDelayLoop-Generator, dort hatte ich aber auch einen Fehler ;)
Gast #5604
Lesenswert?

Ob das so gut geht wenn man einfach in einem eingebetteten Assemblercode 
ein paar Register überklatscht ohne den Compiler zu informieren? Auch 
wenn es sich um eine eigenständige Funktion handelt hätte ich hierbei 
trotzdem schwerste Bedenken. Das muss ja nicht notwendigerweise 
bedeuten, dass der Compiler alle seine Register leerräumt. Aber er wird 
es ja merken, wenn auf einmal seltsame Effekte auftreten.

Gruss,

Peter
Gast #5605
Lesenswert?

Hast du nen besseren Vorschlag was man machen könnte?

Ich hatte zuerst auch folgenden Code:

void delay05(void)
{
  int i;

  for(i=0; i < 833; i++)
  {
    asm volatile("nop"::);
  }
}

Macht genau das selbe, nur das Problem ist nur das ich nicht weiß 
wieviel Zyklen die For-Schleife pro Durchgang beansprucht und bei meinem 
Programm muss ich relativ genau sein.
Gast #5606
Lesenswert?

> Hast du nen besseren Vorschlag was man machen könnte?
Ich benutze den angehängten Code dafür. Ist zwar etwas umfangreicher (51 
Bytes), dafür aber auch genau und sauber/sicher.

> ich nicht weiß wieviel Zyklen die For-Schleife pro Durchgang beansprucht und bei 
meinem Programm muss ich relativ genau sein.

Ich habe den Code mittels AVR-Studio ausgemessen.

Schmittchen.
Angehängte Dateien:
Gast #5609
Lesenswert?

Das mit dem eingebetteten Assembler ist ja an sich ok, man sollte nur 
die Clobber-Liste ausfüllen, damit der Compiler weiss, welche Register 
man für seinen eigenen Code in Beschlag nimmt. Hier hat sich nämlich ein 
netter Kollege mal die Mühe gemacht, einen Code-Generator (Assembler) 
für Warteschleifen zu programmieren, der einem für jede gewünschte 
Verzögerung den exakten Code ausgibt. Den so erzeugten Assembler-Code 
kann man z.B. gut in C einbetten. Wenn man einmal die zusätzliche Zeit 
für den Funktionsaufruf in C ermittelt hat, kann man sich fortan 
Verzögerungsroutinen auf den Taktzyklus genau programmieren ohne das 
Timing mit dem AVR-Studio jedesmal zurechtfutscheln zu müssen. Nur mal 
so als Tip.

Gruss,

Peter
Gast #5610
Lesenswert?

hmmm.. die frage ist: dauert der funktionsaufruf nicht länger für ne 
warteschleife, die 3 regs benutzt, als eine, die 2 benutzt? der compiler 
muss doch vorher dann die regs sichern und zurückholen... oder ist die 
clobber liste global?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren