2011-07-11 37 views
8

Estoy un poco confundido por el comentario en uno de los archivos de cabecera para el kernel de Linux, arch/x86/include/asm/nops.h. Afirma que¿Es mov% esi,% esi no-operativo o no en x86-64?

< ...> las siguientes instrucciones no son NOP en modo de 64 bits, 64 bits para el uso del modo K8 o NOP P6 en lugar
MOVL% esi,% esi
Leal (0x00 esi%),% esi
< ...>

supongo que el autor implícito las instrucciones de la máquina (F6' '89 y '8D 76 00', respectivamente) allí en lugar de instrucciones de montaje. Se sigue de la descripción de LEA en el Manual del Desarrollador de Software Intel Vol 2A que la última instrucción (lea 0x00(%rsi), %esi) hace lo mismo que la anterior, mov %esi,%esi.

Así que esto reduce a la pregunta, si mov %esi,%esi es en realidad un no-op en x86-64.

mov no cambia de banderas. Este tipo de mov tampoco cambia la memoria. Parece, si cambia algo además de %rip, eso debería ser registros de propósito general. Pero no tengo idea de cómo puede cambiar el contenido de %rsi o lo que sea. Si manipulas la mitad inferior de un registro de propósito general, la mitad superior no debería cambiar, ¿verdad?

Respuesta

15
mov %esi, %esi 

elimina los 32 bits de% rsi, y por lo tanto no es un no-op en x86_64.

+3

viendo como su tipo de montaje, y esta es su respuesta 486a, ¿significa esto que dejará de responder preguntas ahora? (Lo siento, cojo 486 broma ... Recuerdo mi 486DX2 ... y ahora estoy COMPLETAMENTE fuera de tema) – Steve

+2

Solo para agregar a la respuesta, la sección relevante de los manuales de desarrollo Intel es 3.4.1.1 (en el Volumen 1) . –

+4

@Steve: La primera plataforma para la que escribí ensamblado fue la de 68k, así que creo que me queda un tiempo antes de que la cuelgue ... –

6
#include <stdio.h> 

int main(int argc, char * argv[]) 
{ 
    void * reg_rsi = 0; 

    asm (
     "movq $0x1234567812345678, %%rsi;\n" 
     "movl %%esi, %%esi;\n" 
     "movq %%rsi, %0;\n" 
     : "=r" (reg_rsi) 
     : /* no inputs */ 
     : /* no clobbered */ 
    ); 

    printf("reg_rsi = %p\n", reg_rsi); 

    return 0; 
} 

Esto da "reg_rsi = 0x12345678" para mi máquina x86_64.

+1

Tiene razón, lo mismo se aplica a 'rax' y' eax'. SIN EMBARGO: cambie el 'movl' por un' xor' y pondrá a cero los 64 bits completos. – Orwellophile

Cuestiones relacionadas