test
це як and
, за винятком того, що він пише лише FLAGS, залишаючи обидва входи незміненими. З двома різними входами корисно перевірити, чи всі біти всі нульові, або якщо принаймні один встановлений. (наприклад, test al, 3
встановлює ZF, якщо EAX кратне 4 (і при цьому обидва його низьких 2 біта нульові).
test eax,eax
встановлює всі прапори точно так само, як cmp eax, 0
і :
За винятком застарілого автофокусу (прапор допоміжного переносу, який використовується інструкціями ASCII / BCD). TEST залишає його невизначеним , але CMP встановлює "відповідно до результату" . Оскільки віднімання нуля не може спричинити перенесення з 4-го по 5-й біт, CMP повинен завжди очищати AF.
TEST менший (не негайний), а іноді і швидший (може макросплавлення перетворитись на порівняння та розгалуження на загальних процесорах у більшості випадків, ніж на CMP). Це робить test
переважну ідіому для порівняння регістра з нулем . Це оптимізація маточок, cmp reg,0
яку ви можете використовувати незалежно від смислового значення.
Єдина поширена причина використання CMP з негайним 0 - це коли ви хочете порівняти з операндом пам'яті. Наприклад, cmpb $0, (%esi)
для перевірки наявності кінцевого нульового байта в кінці рядка C стилю неявної довжини.
AVX512F додаєkortestw k1, k2
і AVX512DQ / BW (Skylake-X, але не KNL), додають ktestb/w/d/q k1, k2
, які працюють на масках AVX512 (k0..k7), але все ще встановлюють звичайні FLAGS, як test
це робить, так само, як це роблять цілі OR
чи AND
інструкції. (На зразок SSE4 ptest
або SSE ucomiss
: введення в домен SIMD і результат у цілому FLAGS.)
kortestw k1,k1
є ідіоматичним способом розгалуження / cmovcc / setcc на основі результату порівняння AVX512, замінюючи SSE / AVX2 (v)pmovmskb/ps/pd
+ test
або cmp
.
Використання jz
порівняно je
може бути заплутаним.
jz
і je
є буквально однаковою інструкцією , тобто тим самим кодом в машинному коді. Вони роблять те саме, але мають різне смислове значення для людини . Розбиральники (і, як правило, вихід ASM від компіляторів) коли-небудь використовуватимуть лише один, тому семантична відмінність втрачається.
cmp
і sub
встановити ZF, коли їх два входи рівні (тобто результат віднімання дорівнює 0). je
(стрибок, якщо рівний) - семантично релевантний синонім.
test %eax,%eax
/ and %eax,%eax
знову встановлює ZF, коли результат дорівнює нулю, але тесту на «рівність» немає. ZF після тесту не говорить про те, чи були два операнди рівними. Отже jz
(стрибок, якщо нуль) - семантично релевантний синонім.