Forum: Mikrocontroller und Digitale Elektronik Das Befehl "nop" bei C


von bob (Gast)


Lesenswert?

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 (...);

von Johannes M. (johnny-m)


Lesenswert?

AVR-GCC-Tutorial, Abschnitt "Assembler und Inline-Assembler"

von Philipp Karbach (Gast)


Lesenswert?

asm("nop");

von Philipp (Gast)


Lesenswert?

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.

von Rolf Magnus (Gast)


Lesenswert?

> 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?

von Bonzo (Gast)


Lesenswert?

Ein einzelner nop hat bei einer Hochsprache nichts zu suchen, der 
Optimizer muss den entfernen.

von bob (Gast)


Lesenswert?

>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;

von opacer (Gast)


Lesenswert?

while(x=0);

?

von opacer (Gast)


Lesenswert?

also das reicht in der regel aus das "Warteschleife"

von hubert (Gast)


Lesenswert?

while(x==0);
       ^^
das reicht!!

von Johannes M. (johnny-m)


Lesenswert?

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")...

von Jörg X. (Gast)


Lesenswert?

>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!

von Fred (Gast)


Lesenswert?

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

von gast (Gast)


Lesenswert?

Solltest Du den IAR_Compiler benutzen so lautet der Befehl :

__no_operation ();

Es muss aber noch #include "intrinsics.h" eingebunden werden

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

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.

...

von Simon K. (simon) Benutzerseite


Lesenswert?

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".

von Chrisi (Gast)


Lesenswert?

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.

von holger (Gast)


Lesenswert?

>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 ;)

von holger (Gast)


Lesenswert?

>Ergo: Der nop ist in jedem Falle nutzlos.

Chrisi du hast keine Ahnung wofür so ein nop gut sein kann.

von Ralph (Gast)


Lesenswert?

für was denn holger ?

von Fred (Gast)


Lesenswert?

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

von holger (Gast)


Lesenswert?

@ 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
}

von Chrisi (Gast)


Lesenswert?

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.

von holger (Gast)


Lesenswert?

>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 ;)

von Simon K. (simon) Benutzerseite


Lesenswert?

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.

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

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

von Chrisi (Gast)


Lesenswert?

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.

von holger (Gast)


Lesenswert?

>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 ?

von Obelix (Gast)


Lesenswert?

@Simon
>> Für Timingzwecke, ja sicher.
> Nö!

> Holger hat doch oben gezeigt, wofür er das Nop braucht

Genau das nennt sich Timingzwecke.

von Rolf Magnus (Gast)


Lesenswert?

> 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.

von Hannes L. (hannes)


Lesenswert?

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
Noch kein Account? Hier anmelden.