アセンブリの「セマンティックNOP」とは何でしょうか。
5 に答える
実際のnopではないが、プログラムの動作に影響を与えないコード。
Cでは、次のシーケンスはセマンティックNOPと考えることができます。
{
// Since none of these have side affects, they are effectively no-ops
int x = 5;
int y = x * x;
int z = y / x;
}
これらは、NOPのように効果はありませんが、より多くのバイトを必要とする命令です。コードをキャッシュラインの境界に揃えるのに便利です。lea edi、[edi + 0]のような命令は一例です。同じバイト数を満たすには、7つのNOPが必要ですが、7ではなく1サイクルしかかかりません。
実行されるが意味のあることは何もしないコード。これらは「不透明な述語」とも呼ばれ、難読化ツールによって最も頻繁に使用されます。
セマンティックNOPは、プログラムが実際に実行していることを難読化することだけを目的とした、まったく効果がないか、ほとんど効果がない(ほとんどの命令が条件コードを変更する)機械語命令のコレクションです。
真の「セマンティックノップ」とは、時間をかけてプログラムカウンターを進める以外に効果のない命令です。レジスタからレジスタへの移動がフラグに影響を与えない多くのマシンには、たとえば、レジスタをそれ自体に移動する多数の命令があります。たとえば、8088では、次のいずれかがセマンティックNOPになります。
mov al、al mov bl、bl mov cl、cl ..。 mov ax、ax mob bx、bx mov cx、cx ..。 xchg ax、ax xchg bx、bx xchg cx、cx ..。
「xchgax、ax」を除く上記のすべてが2バイトの命令であることに注意してください。したがって、Intelは、1バイトのNOPが必要な場合は、「xchg ax、ax」を使用する必要があると宣言しています。実際、「mov ax、ax」を組み立てて分解すると、「NOP」として分解されます。
場合によっては、命令または命令シーケンスに潜在的な副作用がある可能性がありますが、それでも通常の「nop」よりも望ましいことに注意してください。たとえば、6502では、7サイクルの遅延が必要で、スタックポインターが有効であるが、スタックの最上位の値が無関係である場合、PHPの後にPLPが続くと、2バイトのコードのみを使用して7サイクルが強制終了されます。ただし、スタックの最上位の値がRAMのスペアバイトでない場合、シーケンスは失敗します。