webentwicklung-frage-antwort-db.com.de

Was bedeutet "rep; nop;" meine in x86 montage? Ist es dasselbe wie die "Pause" -Anweisung?

  • Was bedeutet rep; nop?
  • Entspricht es der Anweisung pause?
  • Ist es dasselbe wie rep nop (Ohne das Semikolon)?
  • Was ist der Unterschied zu der einfachen Anweisung nop?
  • Verhalten sich AMD- und Intel-Prozessoren unterschiedlich?
  • (Bonus) Wo befindet sich die offizielle Dokumentation für diese Anleitung?

Motivation für diese Frage

Nach einigen Diskussionen in den Kommentaren von eine andere Frage wurde mir klar, dass ich nicht weiß, was rep; nop; In der x86 oder x86-64-) Assembly bedeutet. Und auch im Web konnte ich keine gute Erklärung finden.

Ich weiß, dass rep ein Präfix ist, das bedeutet "wiederhole die nächste Anweisung cx mal" (oder zumindest es war, in alten 16-Bit-x86-Assembly). Nach diesem --- (Übersichtstabelle bei Wikipedia scheint rep nur mit movs, stos, cmps, lods, _ verwendbar zu sein [$ var] _, scas (aber möglicherweise wurde diese Einschränkung auf neueren Prozessoren entfernt). Ich würde also denken, rep nop (Ohne Semikolon) würde eine nop -Operation cx mal wiederholen.

Nach weiteren Recherchen wurde ich jedoch noch verwirrter. Es scheint, dass rep; nop Und pausedem exakt gleichen Opcode zuordnen und pause ein etwas anderes Verhalten haben als nur nop . Einige alte Mail von 2005 sagten verschiedene Dinge:

  • "versuche nicht zu viel Strom zu verbrennen"
  • "es ist gleichbedeutend mit 'nop' nur mit 2-Byte-Codierung."
  • "Es ist magisch auf Intel. Es ist wie 'Nein, aber lass das andere HT-Geschwister laufen'"
  • "es ist Pause auf Intel und schnelles Auffüllen auf Athlon"

Mit diesen unterschiedlichen Meinungen konnte ich die richtige Bedeutung nicht verstehen.

Es wird im Linux - Kernel (sowohl auf i386 als auch x86_64 ) zusammen mit folgendem Kommentar verwendet: /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ Es wird auch verwendet in BeRTOS , mit dem gleichen Kommentar.

76

rep; nop ist in der Tat dasselbe wie die Anweisung pause (Opcode F390). Es kann für Assembler verwendet werden, die die Anweisung pause noch nicht unterstützen. Auf früheren Prozessoren hat dies einfach nichts bewirkt, genau wie nop, jedoch in zwei Bytes. Bei neuen Prozessoren, die Hyperthreading unterstützen, wird dies als Hinweis für den Prozessor verwendet, dass Sie einen Spinloop ausführen, um die Leistung zu steigern. Von Intels Anweisungsreferenz :

Verbessert die Leistung von Spin-Wait-Schleifen. Bei der Ausführung einer "Spin-Wait-Schleife" erleidet ein Pentium 4- oder Intel Xeon-Prozessor beim Verlassen der Schleife eine erhebliche Leistungseinbuße, da er einen möglichen Verstoß gegen die Speicherreihenfolge erkennt. Der PAUSE-Befehl gibt dem Prozessor einen Hinweis darauf, dass die Codesequenz eine Spin-Wait-Schleife ist. Der Prozessor verwendet diesen Hinweis, um die Verletzung der Speicherreihenfolge in den meisten Situationen zu vermeiden, wodurch die Prozessorleistung erheblich verbessert wird. Aus diesem Grund wird empfohlen, in alle Spin-Wait-Schleifen einen PAUSE-Befehl einzufügen.

66
ughoavgfhw

Präfixe, die sich nicht auf eine Anweisung beziehen, werden ignoriert. Zukünftige CPUs können diese Bytefolge jedoch zum Codieren eines neuen Befehls verwenden. (Ja, der x86-Opcode-Speicherplatz ist so begrenzt, dass sie solche verrückten Sachen machen, und ja, das macht die Decoder kompliziert.)

In diesem Fall bedeutet , dass Sie pause in Spinloops verwenden können, ohne die Rückwärtskompatibilität zu unterbrechen. Alte CPUs, die sich mit pause nicht auskennen, dekodieren es als NOP, ohne dass dies Schaden anrichtet. Auf neuen CPUs profitieren Sie von Energieeinsparung/HT-Freundlichkeit und Vermeidung von Fehlspekulationen in Bezug auf die Speicherreihenfolge wenn sich der Speicher ändert und Sie die Spinschleife verlassen.


Links zu Intels Handbüchern und vielen anderen nützlichen Informationen auf der Wiki-Infoseite für x86-Tags: https://stackoverflow.com/tags/x86/info

Ein weiterer Fall, in dem ein bedeutungsloses rep -Präfix zu einer neuen Anweisung auf neuen CPUs wird: lzcnt ist F3 0F BD /r. Auf CPUs, die diesen Befehl nicht unterstützen (das LZCNT-Feature-Flag in ihrer CPUID fehlt), wird der Befehl als rep bsr Dekodiert, der mit bsr identisch ist. Auf alten CPUs erzeugt es also 32 - expected_result Und ist undefiniert, als die Eingabe Null war.


Ein Fall eines bedeutungslosen rep -Präfixes, das wahrscheinlich niemals anders dekodiert wird: rep ret Wird standardmäßig von gcc verwendet, wenn "generische" CPUs anvisiert werden (dh keine bestimmte CPU mit -march oder -mtune und nicht für AMD K8 oder K10.) Es wird Jahrzehnte dauern, bis jemand eine CPU herstellen kann, die rep ret als etwas anderes als ret dekodiert, weil es vorhanden ist in den meisten Binärdateien in den meisten Linux-Distributionen. Siehe Was bedeutet "rep ret"?

9
Peter Cordes