2012-06-24 53 views
68

Desde el x86-64 Tour of Intel Manuals, leí¿Por qué las instrucciones x86-64 en registros de 32 bits ponen a cero la parte superior del registro completo de 64 bits?

Quizás el hecho más sorprendente es que una instrucción tal como MOV EAX, EBX pone a cero automáticamente 32 bits superiores del registro RAX.

La documentación Intel (3.4.1.1 Registros de uso general en modo de 64 bits en la arquitectura Manual básico) establecida a la misma fuente nos dice:

  • operandos de 64 bits generar una 64 -bit resultado en el registro de propósito general de destino.
  • Los operandos de 32 bits generan un resultado de 32 bits, cero extendido a un resultado de 64 bits en el registro de destino general.
  • 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 x86-32 y x86-64 de montaje, instrucciones de 16 bits como

mov ax, bx 

no muestran 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).

+11

Si buscas en Google "Puesto de registro parcial", encontrarás bastante información sobre el problema que estaban (casi con certeza) tratando de evitar. –

+3

http://stackoverflow.com/questions/25455447/x86-64-registers-rax-eax-ax-al-overwriting-full-register-contents –

+1

No solo "la mayoría".Las instrucciones AFAIK, * all * con un operando de destino 'r32' ponen a cero el alto 32, 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 forma idéntica. Aunque la [sección Operación del manual] (http://www.felixcloutier.com/x86/PMOVMSKB.html) enumera las 6 combinaciones de fuente de 32/64bit y 64/128/256b por separado, la extensión cero implícita de la forma r32 duplica la extensión cero explícita de la forma r64. Tengo curiosidad sobre la implementación de HW ... –

Respuesta

55

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 modo de 64 bits tendría que esperar en algo que sucedió antes, aunque esa parte alta casi nunca se usarí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.

+7

No creo que sea extraño, creo que no quisieron romper demasiado y mantuvieron el viejo comportamiento allí. –

+3

@Alex cuando introdujeron el modo de 32 bits, no hubo un comportamiento antiguo para la parte alta. No había una parte alta antes ... Por supuesto, después de eso ya no se podía cambiar. – harold

+1

Estaba hablando de operandos de 16 bits, ¿por qué los bits superiores no se ponen a cero en ese caso? No lo hacen en modos que no sean de 64 bits. Y eso también se mantiene en el modo de 64 bits. –

6

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 rompería el código anterior.

+4

Si eso es correcto, ¿no tendría más sentido que firme-amplíe en lugar de 0-extienda? –

+0

@Damien_The_Unbeliever Posiblemente. Pero la extensión cero es extremadamente barata. –

+2

@Alex: ¿Y la extensión de firma no? Ambos pueden hacerse a muy bajo costo en hardware. – jalf

Cuestiones relacionadas