test
es como and
, excepto que solo escribe BANDERAS, dejando ambas entradas sin modificar. Con dos entradas diferentes , es útil para probar si algunos bits son todos cero, o si al menos uno está configurado. (por ejemplo, test al, 3
establece ZF si EAX es un múltiplo de 4 (y por lo tanto tiene ambos bits bajos de 2 en cero).
test eax,eax
establece todas las banderas de la misma manera que cmp eax, 0
lo haría :
Excepto por el AF obsoleto (indicador de transporte auxiliar, utilizado por las instrucciones ASCII / BCD). TEST lo deja sin definir , pero CMP lo establece "según el resultado" . Dado que restar cero no puede producir un acarreo del cuarto al quinto bit, CMP siempre debe borrar AF.
TEST es más pequeño (no inmediato) y, a veces, más rápido (puede macro-fusionarse en un uop de comparación y ramificación en más CPU en más casos que CMP). Eso lo convierte en test
el idioma preferido para comparar un registro con cero . Es una optimización de mirilla cmp reg,0
que puede utilizar independientemente del significado semántico.
La única razón común para usar CMP con un 0 inmediato es cuando desea comparar con un operando de memoria. Por ejemplo, cmpb $0, (%esi)
para comprobar si hay un byte de terminación cero al final de una cadena de estilo C de longitud implícita.
AVX512F agregakortestw k1, k2
y AVX512DQ / BW (Skylake-X pero no KNL) agrega ktestb/w/d/q k1, k2
, que operan en registros de máscara AVX512 (k0..k7) pero aún establecen BANDERAS regulares como lo test
hacen, de la misma manera que lo hacen los números enteros OR
o las AND
instrucciones. (Algo así como SSE4 ptest
o SSE ucomiss
: entradas en el dominio SIMD y dan como resultado BANDERAS enteras).
kortestw k1,k1
es la forma idiomática de bifurcar / cmovcc / setcc basada en un resultado de comparación AVX512, reemplazando SSE / AVX2 (v)pmovmskb/ps/pd
+ test
o cmp
.
El uso de jz
vs. je
puede resultar confuso.
jz
y je
son literalmente la misma instrucción , es decir, el mismo código de operación en el código de máquina. Hacen lo mismo, pero tienen un significado semántico diferente para los humanos . Los desensambladores (y generalmente la salida de asm de los compiladores) solo usarán uno, por lo que se pierde la distinción semántica.
cmp
y sub
establecer ZF cuando sus dos entradas son iguales (es decir, el resultado de la resta es 0). je
(saltar si es igual) es el sinónimo semánticamente relevante.
test %eax,%eax
/ and %eax,%eax
nuevamente establece ZF cuando el resultado es cero, pero no hay una prueba de "igualdad". ZF después de la prueba no le dice si los dos operandos eran iguales. Entonces jz
(saltar si cero) es el sinónimo semánticamente relevante.