83 Stimmen

Welchen Zweck erfüllt der Opcode CIL nop?

Ich gehe gerade MSIL durch und stelle fest, dass es eine Menge nop Anweisungen in der MSIL.

Im MSDN-Artikel heißt es, dass sie keine Aktion ausführen und zum Auffüllen des Platzes verwendet werden, wenn der Opcode gepatcht wird. Sie werden viel mehr in Debug-Builds als in Release-Builds verwendet.

Ich weiß, dass diese Art von Anweisungen in Assembler-Sprachen verwendet werden, um spätere Anweisungen auszurichten, aber warum sind MSIL nops in MSIL erforderlich?

(Anmerkung des Herausgebers: Die akzeptierte Antwort bezieht sich auf Maschinencode-NOPs, nicht auf MSIL/CIL-NOPs, nach denen die Frage ursprünglich gestellt wurde).

19 Stimmen

Es gibt in diesen Antworten eine große Verwirrung zwischen der MSIL nop-Anweisung, die vom Sprachcompiler in die Assemblerdatei ausgegeben wird, und den x86 nop-Anweisungen (auf dieser Plattform), die vom JIT-Compiler ausgegeben werden, wenn die Assemblerdatei ausgeführt wird. [Idealerweise sollte diese Frage in 2 verschiedene Fragen aufgeteilt werden: Zweck von MSIL::nop? und Zweck von native platform nop?

109voto

Anthony Williams Punkte 64334

NOPs dienen mehreren Zwecken:

  • Sie ermöglichen es dem Debugger, einen Haltepunkt in einer Zeile zu setzen, auch wenn diese mit anderen Zeilen im generierten Code kombiniert ist.
  • Sie ermöglicht es dem Lader, einen Sprung mit einem Zielversatz anderer Größe zu versehen.
  • Sie ermöglicht es, einen Codeblock an einer bestimmten Grenze auszurichten, was für die Zwischenspeicherung nützlich sein kann.
  • Es ermöglicht das inkrementelle Linken, um Codeabschnitte mit einem Aufruf eines neuen Abschnitts zu überschreiben, ohne dass sich die Größe der Gesamtfunktion ändern muss.

0 Stimmen

Desde Wikipedia : "Ein NOP wird meist zu Timing-Zwecken verwendet, um eine Speicherausrichtung zu erzwingen, Gefahren zu verhindern, einen Verzweigungsverzögerungsschlitz zu belegen, eine vorhandene Anweisung wie einen Sprung ungültig zu machen oder als Platzhalter, der später in der Programmentwicklung durch aktive Anweisungen ersetzt wird (oder um entfernte Anweisungen zu ersetzen, wenn eine Umstrukturierung problematisch oder zeitaufwändig wäre). In einigen Fällen kann ein NOP geringfügige Nebeneffekte haben; bei den Prozessoren der Motorola 68000-Serie beispielsweise bewirkt der NOP-Opcode eine Synchronisierung der Pipeline."

12voto

Steve Steiner Punkte 5259

So geht's MSIL / CIL nops ( nicht x86-Maschinencode nop ) werden bei der Fehlersuche verwendet:

Nops werden von Sprachcompilern (C#, VB, etc.) verwendet, um implizite Sequenzpunkte zu definieren. Diese teilen dem JIT-Compiler mit, wo sichergestellt werden soll, dass Maschinenanweisungen auf IL-Anweisungen zurückgeführt werden können.

Rick Byers Blogeintrag zu DebuggingModes.IgnoreSymbolStoreSequencePoints erklärt einige Details.

C# platziert auch Nops nach Aufrufanweisungen, so dass die Rückgabestelle im Quellcode der Aufruf ist und nicht die Zeile nach dem Aufruf.

1 Stimmen

C# platziert auch Nops nach Aufrufanweisungen, so dass die Rückgabestelle im Quellcode der Aufruf ist und nicht die Zeile nach dem Aufruf. Ich bin nicht sicher, ob ich das verstehe. Haben Sie eine Referenz zur Verfügung?

9voto

harpo Punkte 39680

Es bietet die Möglichkeit, zeilenbasierte Markierungen (z. B. Haltepunkte) im Code zu setzen, wo ein Release-Build keine ausgeben würde.

0 Stimmen

Müssen Haltepunkte auf einem nop sein? Warum nicht einfach einen Haltepunkt auf den regulären Opcode setzen?

4 Stimmen

Eine Menge regulärer Opcodes werden in Release-Builds wegoptimiert. Das würde Ihre Haltepunkte durcheinander bringen, es sei denn, es gäbe einen Platzhalter nop dort würden die Haltepunkte immer noch auf

1 Stimmen

In Debug-Builds werden sie auch verwendet, um eine Anweisung bereitzustellen, bei der der Code keine Anweisung enthält. Öffnende geschweifte Klammern, zum Beispiel.

6voto

plinth Punkte 46829

Kumpel! No-op ist genial! Es ist eine Anweisung, die nichts anderes tut, als Zeit zu verbrauchen. In den düsteren dunklen Zeiten würde man ihn für Mikroanpassungen des Timings in kritischen Schleifen oder, was noch wichtiger ist, als Füller in selbstmodifizierendem Code verwenden.

0 Stimmen

Ich verstehe seine Verwendung, wenn es direkt auf der Hardware ausgeführt wird, aber MSIL ist JITed.

0 Stimmen

MSIL wird nur auf Systemen mit JIT ausgeführt - MSIL verlangt kein JIT.

6voto

peterchen Punkte 39679

Es kann auch dazu führen, dass Code schneller läuft, wenn er für bestimmte Prozessoren oder Architekturen optimiert wird:

Prozessoren verwenden seit langem mehrere Pipelines, die ungefähr parallel arbeiten, so dass zwei unabhängige Befehle gleichzeitig ausgeführt werden können. Bei einem einfachen Prozessor mit zwei Pipelines kann die erste alle Befehle unterstützen, während die zweite nur eine Teilmenge unterstützt. Außerdem kommt es zu Verzögerungen zwischen den Pipelines, wenn eine der Pipelines auf das Ergebnis einer vorherigen, noch nicht abgeschlossenen Anweisung warten muss.

Unter diesen Umständen ist eine spezielle nop kann die nächste Anweisung in eine bestimmte Pipeline zwingen (die erste oder nicht die erste) und die Paarung der folgenden Anweisungen verbessern, so dass die Kosten der nop ist mehr als amortisiert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X