test
に似and
ていますが、FLAGS のみを書き込み、両方の入力を変更しない点が異なります。2 つの異なる入力を使用すると、一部のビットがすべてゼロかどうか、または少なくとも 1 つが設定されているかどうかをテストするのに役立ちます。(たとえばtest al, 3
、EAX が 4 の倍数の場合 (したがって、下位 2 ビットが両方ともゼロになっている場合)、ZF を設定します)。
test eax,eax
すべてのフラグをまったく同じ方法で設定しcmp eax, 0
ます。
- CF と OF がクリアされます (AND/TEST は常にそれを行います。ゼロを減算してもキャリーは発生しません)。
- EAX の値に応じた ZF、SF、および PF。(
a = a&a = a-0
)。
(通常の PFは、下位 8 ビットに従ってのみ設定されます)
廃止された AF (ASCII/BCD 命令で使用される補助キャリー フラグ) を除きます。 TEST は undefinedのままにしますが、CMP は「結果に従って」設定します。ゼロを減算しても 4 番目から 5 番目のビットへのキャリーを生成できないため、CMP は常に AF をクリアする必要があります。
TEST はより小さく (即時ではなく)、時には高速です (CMP よりも多くの場合、より多くの CPU で比較分岐 uop にマクロ融合できます)。 これによりtest
、レジスタをゼロと比較するための推奨イディオムが作成されます。cmp reg,0
これは、セマンティックな意味に関係なく使用できるのぞき穴の最適化です。
即値 0 で CMP を使用する唯一の一般的な理由は、メモリ オペランドと比較する場合です。たとえばcmpb $0, (%esi)
、暗黙的な長さの C スタイルの文字列の末尾にゼロ バイトがあるかどうかを確認するには、次のようにします。
AVX512F はkortestw k1, k2
ktestb/w/d/q k1, k2
、 AVX512 マスク レジスタ (k0..k7) で動作するAVX512DQ/BW (KNL ではなく Skylake-X) add を追加しますtest
が、整数OR
またはAND
命令と同じ方法で通常の FLAGS を設定します。(SSE4ptest
や SSEのようなものucomiss
: SIMD ドメインの入力であり、整数の FLAGS になります。)
kortestw k1,k1
SSE/AVX2 (v)pmovmskb/ps/pd
+test
またはcmp
.
jz
vsの使用はje
混乱を招く可能性があります。
jz
とje
は、文字通り同じ命令、つまりマシンコードの同じオペコードです。 それらは同じことを行いますが、人間にとって異なる意味を持ちます。逆アセンブラー (および通常はコンパイラーからの asm 出力) は 1 つしか使用しないため、セマンティックの区別は失われます。
cmp
sub
2 つの入力が等しい場合 (つまり、減算結果が 0 の場合)、ZF を設定します。je
(等しい場合はジャンプ) は、意味的に関連する同義語です。
test %eax,%eax
/and %eax,%eax
は、結果がゼロの場合に再び ZF を設定しますが、「等しい」テストはありません。テスト後の ZF は、2 つのオペランドが等しいかどうかを示しません。したがってjz
、(jump if zero) は意味的に関連する同義語です。