hallo Leute, mal ne einfache Frage ;) bei Assembler gibts ja dieses Befehl "nop" einfach um nichts zu tun. wie heißt dieses Befehl bei C? habs leider nirgends gefunden! z. B.: do { "nop"; } while (...);
Ich kenne Deinen Compiler nicht, aber meist sollte es mit asm nop; funktionieren. Und vorher bitte immer zwei Mal überlegen, ob so eine Krücke wirklich nötig ist.
> bei Assembler gibts ja dieses Befehl "nop" einfach um nichts zu tun. > wie heißt dieses Befehl bei C? habs leider nirgends gefunden! Wozu sollte man sowas in C brauchen?
Ein einzelner nop hat bei einer Hochsprache nichts zu suchen, der Optimizer muss den entfernen.
>Wozu sollte man sowas in C brauchen?
mein Programm soll solange an dieser Stelle warten bis ein Zwischenfall
passiert. z.b. Interrupt, da setze ich irgendein Variable auf =1 und
erst dann kann ich ab dieser Stelle weiter durchlaufen.
ich hoffe, ich konnte es erklären :)
do
{
"nop";
}
while (x=0);
weitere Anweisungen;
Bonzo wrote: > Ein einzelner nop hat bei einer Hochsprache nichts zu suchen, der > Optimizer muss den entfernen. Wenn der "nop" volatile ist, dann DARF der Optimizer den gar nicht entfernen. Der Optimizer hat i.d.R. von Inline-Assembler-Abschnitten die Finger zu lassen. Einzelne "nop"s werden durchaus verwendet, um ansonsten leere Schleifen vor einer Wegoptimierung zu bewahren (wobei allerdings die Verwendung von irgendwelchen Zählschleifen undefinierbaren Zeitverhaltens sowieso vermieden werden sollte, aber das steht auf einem anderen Blatt). BTW: In CodeVision-AVR heißt es einfach #asm("nop")...
>while(x==0); > ^^ >das reicht!! wenn x volatile ist , dann ja ;) Sonst haben wir (endlich) wieder eine Diskussion, dass der Compiler (sinnlose/unlogische ) Programme kaputt macht. scnr --Jörg ps.: bei größeren/größer werdenden Programmen ist es so besser
1 | // main loop
|
2 | for(;;){ // oder while(1) oder.. egal |
3 | //tu was
|
4 | if(x==0) |
5 | tu_was(); |
6 | if(/*andere bedingung*/) |
7 | ....
|
8 | //...
|
9 | }
|
dann kann man die Wartezeiten für was anders nutzen, wenn die lang genug sind!
Hi, also wenn der µC einfach nur auf etwas warten soll und derweil nix zu tun hat, dann schick ihn doch schlafen. Zumindest im Batteriebetrieb ist sowas immer ratsam. Gruß Fred
Solltest Du den IAR_Compiler benutzen so lautet der Befehl : __no_operation (); Es muss aber noch #include "intrinsics.h" eingebunden werden
Rolf Magnus wrote: >> bei Assembler gibts ja dieses Befehl "nop" einfach um nichts zu tun. >> wie heißt dieses Befehl bei C? habs leider nirgends gefunden! > > Wozu sollte man sowas in C brauchen? Beispiel: Man muss mal 50 oder 100ns auf externe Peripherie warten, bis die ihren Response ausspucken. Da lohnts sich ja nicht wirklich, was anderes zu machen in der Zwischenzeit.
Simon Küppers wrote: > Rolf Magnus wrote: >>> bei Assembler gibts ja dieses Befehl "nop" einfach um nichts zu tun. >>> wie heißt dieses Befehl bei C? habs leider nirgends gefunden! >> >> Wozu sollte man sowas in C brauchen? > > Beispiel: Man muss mal 50 oder 100ns auf externe Peripherie warten, bis > die ihren Response ausspucken. Da lohnts sich ja nicht wirklich, was > anderes zu machen in der Zwischenzeit. Sollte man da nicht lieber die Wait-Funktion aus der AVR-LibC benutzen? Die optimiert der Compiler wenigstens nicht weg. ;-) Aber ich kann mich da auch irren, ich werkele in ASM. ...
Hannes Lux wrote: > Sollte man da nicht lieber die Wait-Funktion aus der AVR-LibC benutzen? > Die optimiert der Compiler wenigstens nicht weg. ;-) > > Aber ich kann mich da auch irren, ich werkele in ASM. > > ... Jau, aber wenn ich nur 1-2 Zyklen warten will, dann sind die _delay_xyz Funktionen nunmal "zu langsam".
So ein nop ist oft in diversen C-Sourcen gesehen. Er soll verhindern, dass solche Schleifen wie int i; for (i=0; i<100; i++) ; // bzw. nop(); nicht komplett wegoptimiert werden. Wenn der Compiler sowas wie int x = 0; do { } while (x == 0); findet, könnte er genauso gut eine Endlosschleife erzeugen, bei der x niemals geprüft wird. Auch ein Aufruf von nop() kann daran nichts ändern. Umgekehrt bei volatile int x = 0; do { } while (x == 0); wird der Compiler x immer prüfen müssen. Daran ändert auch ein nop in der Schleife nichts. Ergo: Der nop ist in jedem Falle nutzlos. Solch heroischen Maßnahmen wie Sleep oder sonstiges sind sicherlich hochkorrekt, aber wer hat in der Hitze des Gefechts die Zeit, den Sleep mal eben zu implementieren? Nur beim Vollprofi schliesst sich dann keine mehrstündige Fehlersuche an. Zumal wir die äußeren Umstände nicht kennen, die den Prozessor wieder aufwecken, bzw. aus der Schleife entlassen.
>Sollte man da nicht lieber die Wait-Funktion aus der AVR-LibC benutzen? >Die optimiert der Compiler wenigstens nicht weg. ;-) >Aber ich kann mich da auch irren, ich werkele in ASM. Wer nur in ASM programmiert hat natürlich keine Ahnung was der Compiler wegoptimiert oder nicht ;) Ein kleines NOP() im C-Code gewöhnt dem Compiler schon mal das wegoptimieren ab wenn es sein muss. #define NOP() asm volatile ("nop" ::) Ein volatile darf der Compiler nicht wegoptimieren. Ich hab meine NOPs im Assemblerlisting jedenfalls immer in voller Anzahl wiedergefunden. >Jau, aber wenn ich nur 1-2 Zyklen warten will, dann sind die _delay_xyz >Funktionen nunmal "zu langsam". Genau. NOPs braucht man auch in C gelegentlich. Bevor die ASM-Freaks was zu "C" sagen, sollten sie es erst einmal lernen. Als C-Freak hab ich ja auch ASM gelernt ;)
>Ergo: Der nop ist in jedem Falle nutzlos.
Chrisi du hast keine Ahnung wofür so ein nop gut sein kann.
Hallo nochmal, vielleicht hab ich die Timing-Sache überlesen. Bei mir sind die notwendigen Pausen bisher fast schon im ms Bereich. Und auch der Rest meiner Programme ist nicht so komplex, dass die Fehlersuche sehr anspruchsvoll wird. Gruß Fred
@ Ralph
>für was denn holger ?
Dafür ?
#define NOP() asm volatile ("nop" ::)
//##########################################################
void CheckBusy(void)
//##########################################################
{
unsigned char by;
DATA_DIR_IN(); //DatenPort auf Eingang zum lesen
CTRL(); //Status Register lesen
do //Schleife Status Bits checken
{
CE_OFF();
RD_OFF();
NOP(); //Ein Waitstate für 8 MHZ
NOP(); //plus noch einen für 16 MHZ
by=READ_DATA(); //Status lesen
RD_ON();
CE_ON();
}while((by&3) != 3); //Solange STA0 oder STA1 = 0
DATA(); //Zurück auf DisplayDaten schreiben
}
Hi holger, Ich habe schon nops programmiert und Clockzyklen gezählt, da hast Du noch mit den Barbiepuppen gespielt ;-) Der nop hat seine Daseinsberechtigung. Für Timingzwecke, ja sicher. Software-UART? Geil! IR-Modulation? Hammer! Das Anliegen des OP war aber ein anderes.
>Ich habe schon nops programmiert und Clockzyklen gezählt, da hast Du >noch mit den Barbiepuppen gespielt ;-) Ich habe selbstmodifizierende Codes in ASM auf Z80 geschrieben als du noch nicht mal geplant warst ;)
Chrisi wrote: > Der nop hat seine Daseinsberechtigung. Richtig. > Für Timingzwecke, ja sicher. Nö! > Software-UART? Geil! IR-Modulation? Hammer! Das Anliegen des OP war aber > ein anderes. Quark. Holger hat doch oben gezeigt, wofür er das Nop braucht, was spricht nun dagegen? Als Waitstate eignet es sich doch perfekt. Oder was würdest DU hier verwenden? Klar gings dem Threadopener nicht darum. Das ganze fing an, als ich Rolf Magnus Behauptung widerlegen wollte: >Rolf Magnus wrote: >>> bei Assembler gibts ja dieses Befehl "nop" einfach um nichts zu tun. >>> wie heißt dieses Befehl bei C? habs leider nirgends gefunden! >> >> Wozu sollte man sowas in C brauchen? >Beispiel: Man muss mal 50 oder 100ns auf externe Peripherie warten, bis >die ihren Response ausspucken. Da lohnts sich ja nicht wirklich, was >anderes zu machen in der Zwischenzeit.
Falls es irgendwie moeglich ist, sollte man nicht aktiv, sondern passiv warten. Wenn die Umgebung also eine sleep bzw. wait-Funktion bereitstellt unbedingt diese nutzen, das ist wesentlich ergonomischer. Michael
Mensch Simon, jetzt ist's aber wieder gut. Wir alle wissen, wozu ein nop gut ist. Es macht keinen Sinn, einen Abend zu diskutieren, nur um dann festzustellen, dass man eh der gleichen Meinung ist. Und ausserdem mag ich keinen Quark. Nicht jetzt.
>Falls es irgendwie moeglich ist, sollte man nicht aktiv, sondern passiv >warten. Wenn die Umgebung also eine sleep bzw. wait-Funktion >bereitstellt unbedingt diese nutzen, das ist wesentlich ergonomischer. @ Michael Ein nop benötigt genau einen Maschinenzyklus des Prozessors. Wie willst du so kurze Wartezeiten mit sleep oder wait Funktionen realisieren ?
@Simon >> Für Timingzwecke, ja sicher. > Nö! > Holger hat doch oben gezeigt, wofür er das Nop braucht Genau das nennt sich Timingzwecke.
> So ein nop ist oft in diversen C-Sourcen gesehen. Er soll verhindern, > dass solche Schleifen wie > > int i; > for (i=0; i<100; i++) > ; // bzw. nop(); > > nicht komplett wegoptimiert werden. In der Schleife muß nur irgendwas stehen, das der Compiler nicht wegoptimieren darf, und dazu muß da kein nop drin sein. Da reicht z.B. auch ein:
1 | asm volatile (""::) |
aus. Oder noch schön mit Kommentar, damit man's im generierten ASM-Code gleich sieht:
1 | asm volatile ("# keep this"::) |
Natürlich kann man das in ein C-Makro schreiben und dieses dann nop()
nennen, aber das hat dann nichts mit dem Assembler-nop zu tun.
> Ergo: Der nop ist in jedem Falle nutzlos.
In C würde ich dem zustimmen. Da halte ich auch die Beispiele, wo es zum
Warten für einen oder zwei Taktzyklen verwendet wird, nicht für
sinnvoll. In C ist das Timingverhalten des Codes sowieso nicht präzise
genug bestimmbar, um taktzyklengenau arbeiten zu können.
Deshalb schreibe ich so timingkritische Codeteile grundsätzlich in
Assembler. Dabei handelt es sich in der Regel um sehr kurze einfache
Teile, die wegen des Timings auch nicht portabel sind. Da würde C dann
auch keinerlei Vorteil bieten.
holger wrote: > Wer nur in ASM programmiert hat natürlich keine Ahnung was > der Compiler wegoptimiert oder nicht ;) > > Bevor die ASM-Freaks was zu "C" sagen, sollten sie es erst einmal > lernen. Als C-Freak hab ich ja auch ASM gelernt ;) > Ich habe selbstmodifizierende Codes in ASM auf Z80 > geschrieben als du noch nicht mal geplant warst ;) Nimmst Du nicht den Mund etwas zu voll? ...
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.