web-dev-qa-db-ja.com

「rep; nop;」とは何ですかx86アセンブリではどうですか? 「一時停止」命令と同じですか?

  • _rep; nop_はどういう意味ですか?
  • pause命令と同じですか?
  • _rep nop_(セミコロンなし)と同じですか?
  • 単純なnop命令との違いは何ですか?
  • AMDプロセッサとIntelプロセッサでは動作が異なりますか?
  • (ボーナス)これらの指示の公式文書はどこにありますか?

この質問の動機

別の質問 のコメントで議論した後、x86(またはx86-64)アセンブリで_rep; nop;_が何を意味するのかわからないことに気付きました。また、ウェブ上で良い説明を見つけることができませんでした。

repは、「次の命令をcx回繰り返す」を意味する接頭辞であることを知っています(または、少なくとも、古い16ビットx86アセンブリ)。これによると Wikipediaの要約表repmovsstoscmpslodsでのみ使用できるようです。 、scas(ただし、この制限は新しいプロセッサでは削除された可能性があります)。したがって、_rep nop_(セミコロンなし)はnop操作cx回を繰り返すと思います。

しかし、さらに検索した後、私はさらに混乱しました。 _rep; nop_およびpauseまったく同じオペコードにマップ 、およびpauseの動作はnopとは少し異なるようです。いくつかの 2005年からの古いメール は異なることを言った:

  • "あまりにも多くの電力を消費しないようにしてください"
  • "2バイトエンコーディングで 'nop'と同等です。"
  • "intelでは魔法です。「nop but like HT兄弟を走らせます」」
  • "Intelでは一時停止、Athlonでは高速パディング"

これらの異なる意見では、正しい意味を理解できませんでした。

Linuxカーネル( i386x86_64 の両方)で使用されており、次のコメントとともに:/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */また、 で使用されていますBeRTOS 、同じコメント付き。

76

rep; nopは、実際にpause命令と同じです(オペコードF390)。 pause命令をまだサポートしていないアセンブラーに使用される場合があります。以前のプロセッサでは、これはnopのように2バイトでしたが、何もしませんでした。ハイパースレッディングをサポートする新しいプロセッサでは、パフォーマンスを向上させるためにスピンループを実行していることをプロセッサへのヒントとして使用します。 Intelの命令リファレンス から:

スピン待機ループのパフォーマンスを改善します。 「スピンウェイトループ」を実行する場合、Pentium 4またはIntel Xeonプロセッサは、メモリ順序違反の可能性を検出するため、ループを終了するときに重大なパフォーマンスペナルティを受けます。 PAUSE命令は、コードシーケンスがスピン待機ループであるというヒントをプロセッサに提供します。プロセッサはこのヒントを使用して、ほとんどの状況でメモリ順序違反を回避します。これにより、プロセッサのパフォーマンスが大幅に向上します。このため、すべてのスピン待機ループにPAUSE命令を配置することをお勧めします。

66
ughoavgfhw

命令に適用されない接頭辞は無視されます。ただし、将来のCPUはそのバイトシーケンスを使用して新しい命令をエンコードできます。 (はい、x86オペコードスペースは非常に限られているため、このようなクレイジーな処理を行います。そうです、デコーダーが複雑になります。)

この場合、これは、後方のcompatを壊すことなく、スピンループでpauseを使用できることを意味します。 pauseを知らない古いCPUは、害のないNOPとしてデコードします。新しいCPUでは、省電力/ HTの使いやすさの利点が得られます。また、 メモリの順序付けの誤った推測を回避 スピンしているメモリが変更され、スピンループが終了した場合。


X86タグwiki情報ページにあるIntelのマニュアルおよびその他の優れたものへのリンク: https://stackoverflow.com/tags/x86/info

意味のないrepプレフィックスが新しいCPUで新しい命令になる別のケース:lzcntF3 0F BD /r。その命令をサポートしていないCPU(CPUIDにLZCNT機能フラグがない)では、rep bsrは、bsrと同じように実行されます。したがって、古いCPUでは、32 - expected_result、および入力がゼロの場合は未定義です。


無意味なrepプレフィックスの1つのケースは、おそらく異なるデコードを行わないでしょう:rep retは、「汎用」CPUをターゲットとするときにgccによってデフォルトで使用されます(つまり、特定のCPUを-marchまたは-mtune、およびAMD K8またはK10をターゲットにしていない。)誰でもrep retは、ほとんどのLinuxディストリビューションのほとんどのバイナリに存在するため、ret以外のものとして。 「rep ret」とはどういう意味ですか? を参照してください

9
Peter Cordes