Pregunta

En el siguiente código de montaje que descargué a cabo utilizando objdump:

lea    0x0(%esi,%eiz,1),%esi

¿Cuál es %eiz registro? Lo que hace la media de código anterior?

¿Fue útil?

Solución

¿Por qué GCC LEA EIZ :?

  

Al parecer %eiz es un pseudo-registro que evalúa sólo a cero en todo momento (como r0 en MIPS).

...

  

Al final encontré una lista de entradas de correo porBinutils gurú Ian Taylor lanza que revela la respuesta. A veces GCC inserta instrucciones NOP en la corriente de código para asegurar una alineación correcta y cosas por el estilo. La instrucción NOP toma un byte, por lo que se podría pensar que usted podría añadir tantos como sea necesario. Pero de acuerdo con la lanza Ian Taylor, que es más rápido para el chip para ejecutar una instrucción larga que muchas instrucciones cortas. Así que en lugar de insertar instrucciones NOP siete, que en lugar de utilizar una LEA bizarro, que utiliza hasta siete bytes y es semánticamente equivalente a un NOP.

Otros consejos

(muy tarde para el juego, pero esto parecía una adición interesante): No es un registro en absoluto, es una peculiaridad de la codificación de instrucciones Intel. Cuando se utiliza un byte ModRM para cargar desde la memoria, hay 3 bits utilizados para el campo de registro para almacenar 8 registros posibles. Pero el lugar donde ESP (el puntero de pila) "sería" en su lugar se interpreta por el procesador como "un byte SIB sigue esta instrucción" (es decir, se trata de un modo de direccionamiento extendido, no una referencia a ESP). Por razones que sólo a los autores, el ensamblador GNU siempre ha representado esta "cero en un registro de lo contrario sería" como "% EIZ" registro. La sintaxis de Intel simplemente deja caer.

Andy Ross ofrece mucho más de los argumentos que sustentan, pero por desgracia es incorrecta o por lo menos confundir por los detalles técnicos. Es cierto que una dirección efectiva de solo (%esp) no puede ser codificado con sólo el byte Modr / M como en lugar de ser decodificada como (%esp), se utiliza para señalar que también se incluye un byte SIB. Sin embargo, el %eiz pseudo-registro no se utiliza siempre con un byte SIB para representar que se utilizó un byte SIB.

El byte SIB (escala / index / base) tiene tres piezas a la misma: el índice (un registro tal como como %eax o %ecx que la escala se aplica a), la escala (una potencia de dos de 1 a 8 que el registro de índice se multiplica por), y la base (otro registro que se agrega al índice reducido). Esto es lo que permite instrucciones tales como add %al,(%ebx,%ecx,2) (código de máquina: 00 04 4b - código de operación, Modr / m, sib (nota ninguna% EIZ registro a pesar de que se utilizó el byte SIB)) (o en la sintaxis de Intel, "añadir BYTE PTR [ecx * 2 + EBX], al ").

Sin embargo, %esp no se puede utilizar como el registro de índice en un byte SIB. En lugar de permitir esta opción, en lugar de Intel añade una opción para utilizar el registro de base como está sin escala o indexación. Por lo tanto para eliminar la ambigüedad entre el caso de add %al,(%ecx) (código de máquina: 00 01 - opcode, Modr / m) y add %al,(%ecx) (código de máquina: 00 04 21 - opcode, Modr / m, sib), el add %al,(%ecx,%eiz,1) sintaxis alternativa se utiliza en lugar (o para Intel sintaxis:. add BYTE PTR [ecx+eiz*1],al)

Y como se explica en el artículo enlazado a por Sinan, esta instrucción específica (lea 0x0(%esi,%eiz,1),%esi) se utiliza simplemente como un multi-byte nop (equivalente a esi = &*esi) para que sólo una nop similar a la instrucción ha de ser ejecutado en lugar de nop múltiple instrucciones.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top