mikrocontroller.net

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


Autor: bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 (...);

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR-GCC-Tutorial, Abschnitt "Assembler und Inline-Assembler"

Autor: Philipp Karbach (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
asm("nop");

Autor: Philipp (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Bonzo (Gast)
Datum:

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

Autor: bob (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: opacer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
while(x=0);

?

Autor: opacer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also das reicht in der regel aus das "Warteschleife"

Autor: hubert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
while(x==0);
       ^^
das reicht!!

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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")...

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
// main loop
for(;;){ // oder while(1) oder.. egal
//tu was
if(x==0)
    tu_was();
if(/*andere bedingung*/)
  ....
//...
}
 dann kann man die Wartezeiten für was anders nutzen, wenn die lang 
genug sind!

Autor: Fred (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Solltest Du den IAR_Compiler benutzen so lautet der Befehl :

__no_operation ();

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

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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.

...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: Chrisi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ergo: Der nop ist in jedem Falle nutzlos.

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

Autor: Ralph (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
für was denn holger ?

Autor: Fred (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
}

Autor: Chrisi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Chrisi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Simon
>> Für Timingzwecke, ja sicher.
> Nö!

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

Genau das nennt sich Timingzwecke.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
asm volatile (""::)

aus. Oder noch schön mit Kommentar, damit man's im generierten ASM-Code 
gleich sieht:
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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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?

...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.