En el Tour x86-64 de los manuales de Intel , 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 delRAX
registro.
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) citada 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, ampliado a 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 o 48 bits superiores (respectivamente) del registro de propósito general de destino no son modificados 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 signo del registro a los 64 bits completos.
En el ensamblaje x86-32 y x86-64, instrucciones de 16 bits como
mov ax, bx
no muestre este tipo de comportamiento "extraño" de que la palabra superior de eax se ponga a cero.
Entonces: ¿cuál es la razón por la que 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).
r32
operando de destino ponen a cero el 32 alto, en lugar de fusionarse. Por ejemplo, algunos ensambladores reemplazarán pmovmskb r64, xmm
con pmovmskb r32, xmm
, guardando un REX, porque la versión de destino de 64 bits se comporta de manera idéntica. Aunque la sección Operación del manual enumera las 6 combinaciones de fuente de 32 / 64bit dest y 64/128 / 256b por separado, la extensión cero implícita del formulario r32 duplica la extensión cero explícita del formulario r64. Tengo curiosidad por la implementación de HW ...
xor eax,eax
o xor r8d,r8d
es la mejor manera de poner a cero RAX o R8 (guardar un prefijo REX para RAX, y XOR de 64 bits ni siquiera se maneja especialmente en Silvermont). Relacionado: ¿Cómo funcionan exactamente los registros parciales en Haswell / Skylake? Escribir AL parece tener una falsa dependencia de RAX, y AH es inconsistente