assembly - relaciona - ¿Por qué las instrucciones x86-64 en registros de 32 bits ponen a cero la parte superior del registro completo de 64 bits?
x8086 (2)
En el x86-64 Tour of Intel Manuales , leí
Quizás el hecho más sorprendente es que una instrucción como
MOV EAX, EBX
automáticamente pone a cero los 32 bits superiores del registroRAX
.
La documentación de Intel (3.4.1.1 Registros de propósito general en modo de 64 bits en la arquitectura básica manual) que se cita en la misma fuente nos dice:
- Los operandos de 64 bits generan un resultado de 64 bits en el registro de propósito general de destino.
- Los operandos de 32 bits generan un resultado de 32 bits, con extensión cero a un resultado de 64 bits en el registro de propósito general de destino.
- Los operandos de 8 y 16 bits generan un resultado de 8 o 16 bits. Los 56 bits superiores o 48 bits (respectivamente) del registro de propósito general de destino no se modifican por la operación. Si el resultado de una operación de 8 bits o de 16 bits está destinado al cálculo de direcciones de 64 bits, extienda explícitamente el registro a los 64 bits completos.
En el ensamblaje x86-32 y x86-64, las instrucciones de 16 bits como
mov ax, bx
no muestre este tipo de comportamiento "extraño" que la palabra superior de eax se pone a cero.
Por lo tanto: ¿cuál es la razón por la cual se introdujo este comportamiento? A primera vista parece ilógico (pero la razón podría ser que estoy acostumbrado a las peculiaridades del ensamblaje x86-32).
No soy AMD ni hablo por ellos, pero lo hubiera hecho de la misma manera. Debido a que poner a cero la mitad alta no crea una dependencia en el valor anterior, la CPU tendría que esperar. El mecanismo de cambio de nombre del registro sería esencialmente derrotado si no se hubiera hecho de esa manera. De esta forma, puede escribir código rápido de 32 bits en modo de 64 bits sin tener que romper dependencias explícitamente todo el tiempo. Sin este comportamiento, cada instrucción de 32 bits en el modo de 64 bits tendría que esperar en algo que sucedió antes, aunque esa parte alta casi nunca se utilizaría.
El comportamiento de las instrucciones de 16 bits es el extraño. La locura de dependencia es una de las razones por las cuales las instrucciones de 16 bits se evitan ahora.
Simplemente ahorra espacio en las instrucciones y el conjunto de instrucciones. Puede mover pequeños valores inmediatos a un registro de 64 bits utilizando instrucciones existentes (32 bits).
También le ahorra tener que codificar valores de 8 bytes para MOV RAX, 42
, cuando se puede reutilizar MOV EAX, 42
.
Esta optimización no es tan importante para operaciones de 8 y 16 bits (porque son más pequeñas), y cambiar las reglas allí también podría romper el código anterior.