assembler - and assembly x86
¿Qué significan los "prefijos de instrucción" en el moderno x86? (2)
Para entender por qué Bulldozer era insatisfactorio, he estado buscando en el excelente libro de microarquitectomía de Agner Fog, en la página 178 debajo del bulldozer tiene este párrafo.
Las instrucciones con hasta tres prefijos pueden decodificarse en un ciclo de reloj. Hay una penalización muy grande para las instrucciones con más de tres prefijos. Las instrucciones con 4-7 prefijos requieren entre 14 y 15 ciclos de reloj adicionales para decodificar. Las instrucciones con 8-11 prefijos toman 20-22 ciclos de reloj adicionales, y las instrucciones con 12-14 prefijos toman 27 - 28 ciclos de reloj adicionales. Por lo tanto, no se recomienda hacer las instrucciones NOP más tiempo con más de tres prefijos. El recuento de prefijos de esta regla incluye el tamaño del operando, el tamaño de la dirección, el segmento, la repetición, el bloqueo, los prefijos REX y XOP. Un prefijo VEX de tres bytes cuenta como uno, mientras que un prefijo VEX de dos bytes no cuenta. Los códigos de escape (0F, 0F38, 0F3A) no cuentan.
Cuando busqué prefijos, fui golpeado con definiciones muy técnicas más allá de mis capacidades. O sugirió que estaban limitados a 4 por instrucción que entra en conflicto con el extracto anterior.
Entonces, en términos simples, ¿alguien puede explicar qué son / hacen y por qué es posible que desee agregar hasta 14+ en una instrucción en lugar de dividirla?
El trato de "cuatro prefijos" viene de los "grupos de prefijos":
- lock / rep / repne
- anulación de segmento
- anular el tamaño del operando
- anular el tamaño de la dirección
Puede repetir prefijos, pero no puede (puede, pero el comportamiento no está definido) usar varios prefijos diferentes del mismo grupo. Aunque eso solo se aplica a los grupos 1 y 2, los otros grupos tienen solo 1 cosa en cada uno.
Algo como 66 66 66 66 66 66 66 66 90
es válido (pero potencialmente lento de decodificar). 2E 3E 00 00
(anulaciones de segmentos de mezcla) no lo es.
Los prefijos de apilamiento pueden ser útiles para la alineación del código cuando los bytes deben ser ejecutados, a diferencia del relleno con nop
, no cuesta tiempo de ejecución. Usar demasiados a la vez puede costarle tiempo a la decodificación.
Normalmente se usan tantas como se necesiten, con la instrucción deseada y los operandos que determinan eso. El ensamblador emite algunos de los prefijos de forma automática, mientras que otros los puedes usar manualmente.
El caso que mencionan es para NOP
múltiples bytes que se usa tradicionalmente para el relleno de alineación donde la idea es usar una instrucción única pero apropiadamente larga para conservar los recursos. Aparentemente, usar más prefijos solo para mantener una sola instrucción puede ser peor que usar dos instrucciones con menos prefijos.
El recuento de prefijos de esta regla incluye el tamaño del operando, el tamaño de la dirección, el segmento, la repetición, el bloqueo, los prefijos REX y XOP. Un prefijo VEX de tres bytes cuenta como uno, mientras que un prefijo VEX de dos bytes no cuenta.
Ejemplos:
- tamaño de operando: puede cambiar entre registros de 32 y 16 bits, por ejemplo
mov ax, [foo]
está codificado igual quemov eax, [foo]
pero con el prefijo66h
- tamaño de dirección: puede cambiar entre tamaños de direcciones de 32/16 o 64/32 bits, por ejemplo,
mov [eax], foo
está codificado igual quemov [rax], foo
pero con el prefijo67h
(en modo de 64 bits) - segmento: puede anular el segmento utilizado, por ejemplo,
mov [fs:eax], foo
se codifica igual quemov [eax], foo
pero con el prefijo64h
. - repetición: se usa con instrucciones de cuerda para repetir, por ejemplo,
rep cmpsb
es el codificado igual quecmpsb
pero con el prefijof3h
- lock: usado con ciertas instrucciones para hacer que sean atómicos, por ejemplo,
lock add [foo], 1
está codificado igual queadd [foo], 1
pero con el prefijof0h
- REX.W: se usa para cambiar al tamaño de operando de 64 bits, por ejemplo,
add rax, 1
se codifica igual queadd eax, 1
pero con el prefijo48h
- REX.R, B, X: se usa como extensiones del byte modr / m para acceder a los registros extra, por ejemplo,
add r8d, 1
es lo mismo queadd eax, 1
pero con el prefijo41h
- XOP, VEX: utilizado con subconjuntos de instrucciones vectoriales