test
seperti and
, kecuali hanya menulis BENDERA, membiarkan kedua inputnya tidak diubah. Dengan dua input yang berbeda , ini berguna untuk menguji apakah beberapa bit semuanya nol, atau jika setidaknya ada satu bit yang disetel. (misalnya test al, 3
set ZF jika EAX adalah kelipatan 4 (dan dengan demikian keduanya memiliki 2 bit rendah yang nol).
test eax,eax
menyetel semua flag dengan cara yang persis sama seperti yang cmp eax, 0
akan :
- CF dan OF dihapus (AND / TEST selalu melakukan itu; mengurangi nol tidak pernah menghasilkan carry)
- ZF, SF dan PF sesuai dengan nilai di EAX. (
a = a&a = a-0
).
(PF seperti biasa hanya diset sesuai dengan low 8 bits )
Kecuali untuk AF yang sudah usang (auxiliary-carry flag, digunakan oleh instruksi ASCII / BCD). TEST membiarkannya tidak terdefinisi , tetapi CMP menetapkannya "sesuai dengan hasil" . Karena mengurangi nol tidak dapat menghasilkan carry dari bit ke-4 hingga ke-5, CMP harus selalu menghapus AF.
TEST lebih kecil (tidak langsung) dan terkadang lebih cepat (dapat melakukan fusi makro menjadi uop pembanding dan cabang pada lebih banyak CPU dalam lebih banyak kasus daripada CMP). Itu membuat test
idiom yang disukai untuk membandingkan register dengan nol . Ini adalah pengoptimalan lubang intip cmp reg,0
yang dapat Anda gunakan terlepas dari arti semantiknya.
Satu-satunya alasan umum untuk menggunakan CMP dengan 0 langsung adalah saat Anda ingin membandingkan dengan operan memori. Misalnya, cmpb $0, (%esi)
untuk memeriksa penghentian byte nol di akhir string gaya-C dengan panjang implisit.
AVX512F menambahkankortestw k1, k2
dan AVX512DQ / BW (Skylake-X tetapi bukan KNL) menambahkan ktestb/w/d/q k1, k2
, yang beroperasi pada register topeng AVX512 (k0..k7) tetapi tetap mengatur BENDERA biasa seperti test
halnya, seperti halnya integer OR
atau AND
instruksi. (Semacam seperti SSE4 ptest
atau SSE ucomiss
: masukan dalam domain SIMD dan menghasilkan BENDERA integer.)
kortestw k1,k1
adalah cara idiomatis untuk mencabangkan / cmovcc / setcc berdasarkan hasil perbandingan AVX512, menggantikan SSE / AVX2 (v)pmovmskb/ps/pd
+ test
atau cmp
.
Penggunaan jz
vs. je
bisa membingungkan.
jz
dan je
secara harfiah merupakan instruksi yang sama , yaitu opcode yang sama dalam kode mesin. Mereka melakukan hal yang sama, tetapi memiliki arti semantik yang berbeda bagi manusia . Disassembler (dan biasanya output asm dari compiler) hanya akan menggunakan satu, sehingga perbedaan semantik hilang.
cmp
dan sub
atur ZF ketika kedua inputnya sama (yaitu hasil pengurangannya adalah 0). je
(lompat jika sama) adalah sinonim yang relevan secara semantik.
test %eax,%eax
/ and %eax,%eax
lagi menyetel ZF saat hasilnya nol, tetapi tidak ada uji "kesetaraan". ZF setelah pengujian tidak memberi tahu Anda apakah kedua operan itu sama. Jadi jz
(lompat jika nol) adalah sinonim yang relevan secara semantik.