tutorial registers lenguaje language instruction ensamblador assembly x86

assembly - registers - lenguaje ensamblador x86



¿Por qué se usaría "movl $ 1,% eax" en lugar de decir, "movb $ 1,% eax"? (6)

opuesto a, digamos, "movb $ 1,% eax"

Esta instrucción no es válida. No puedes usar eax con la instrucción movb. En su lugar, debería utilizar un registro de 8 bits. Por ejemplo:

movb $ 1, $ al

¿pero no es% eax un registro que sea equivalente al tamaño del tamaño de las palabras del sistema?

No. EAX siempre tendrá un valor de 32 bits, independientemente del tamaño de registro del sistema.

Estás confundiendo los tamaños de variable C con los tamaños de registro. Los tamaños variables de C pueden cambiar dependiendo de su sistema y compilador.

El ensamblaje es más simple que C. En el ensamblaje de GAS, las instrucciones están marcadas con las letras "b", "s", "w", "l", "q" o "t" para determinar el tamaño del operando que se manipula.

* b = byte (8 bit) * s = short (16 bit integer) or single (32-bit floating point) * w = word (16 bit) * l = long (32 bit integer or 64-bit floating point) * q = quad (64 bit) * t = ten bytes (80-bit floating point)

Estos tamaños son constantes. Ellos nunca serán cambiados. al es siempre de 8 bits y eax es siempre de 32 bits.

Como dice el título, ¿por qué uno usaría "movl $ 1,% eax" en lugar de decir "movb $ 1,% eax"? % eax un registro que es equivalente al tamaño del tamaño de las palabras del sistema? lo que significa que movl es en realidad una operación de entero (¿y no es larga?)

Estoy claramente un poco confundido acerca de todo esto; Gracias.


En una máquina de 32 bits,% eax es un registro de 4 bytes (32 bits). movl escribirá en los 4 bytes. En su ejemplo, pondrá a cero los 3 bytes superiores y pondrá 1 en el byte más bajo. El movb solo cambiará el byte de orden bajo.


Su segunda opción solo producirá un error, x86 no tiene esa instrucción. X86 es un poco único con respecto a la carga de bytes en ciertos registros. Sí, en la mayoría de las arquitecturas de conjuntos de instrucciones, el operando es cero o con signo extendido, pero x86 le permite escribir solo el byte inferior o los 16 bits inferiores de algunos de ellos.

Ciertamente hay otras opciones, como borrar el registro y luego incrementarlo, pero aquí hay tres opciones que inicialmente parecen razonables:

0: b8 01 00 00 00 movl $0x1,%eax 5: 31 c0 xorl %eax,%eax 7: b0 01 movb $0x1,%al 9: b0 01 movb $0x1,%al b: 0f b6 c0 movzbl %al,%eax

El primero es de 5 bytes, el segundo de 4, el tercero de 5. Entonces, el segundo es la mejor opción si se optimiza para el espacio, de lo contrario, supongo que el que corre más rápido es el primero. X86 está muy canalizado en estos días, por lo que las dos instrucciones se interconectarán y la máquina puede necesitar algunos estados de espera dependiendo de los detalles del hardware de la tubería.

Por supuesto, estas operaciones x86 se están traduciendo en formas específicas de la CPU en microoperaciones de CPU , y por lo tanto, quién sabe qué sucederá.


originalmente era de 32 bits, mientras que int y short eran 16. Y los nombres de los códigos de operación no cambian cada vez que alguien sale con un nuevo sistema operativo.


%eax es de 32 bits en máquinas de 32 bits. %ax es de 16 bits, y %ah y %al son sus constituyentes de 8 bits de alto y bajo.

Por lo tanto, movl es perfectamente válido aquí. En movb eficiencia, movl será tan rápido como movb , y poner a cero los 3 bytes altos de %eax es a menudo una propiedad deseable. Es posible que desee utilizarlo como un valor de 32 bits más adelante, por lo que movb no es una buena manera de mover un byte allí.


%eax es un registro de 32 bits. Para usar un ancho menor, necesita %ax para 16 bits. %ax puede dividirse adicionalmente en %ah para el byte alto de %ax , y %al para el byte inferior. Lo mismo ocurre con los otros x86 GPRs.

Mirando la referencia del conjunto de instrucciones de Intel para la instrucción mov , no veo una variante que pueda mover un solo byte a un registro de 32 bits; probablemente se interprete como un movimiento a %al .

Como movl es una instrucción de 32 bits, los valores de los bytes superiores corresponderán a ceros en el caso de un valor inmediato . Si se estuviera moviendo de la memoria, estaría moviendo una palabra completa de 32 bits.

%eax no se pone a cero a menos que movl $0, %eax , o si xorl %eax, %eax . De lo contrario, tiene cualquier valor que haya previamente allí. Cuando movl $1, %eax , terminará con 0x00000001 en el registro porque la instrucción de 32 bits mueve un valor inmediato de 32 bits al registro.