book - x86 assembly
¿Cuál es el 0x10 en la instrucción de ensamblaje "leal 0x10(% ebx),% eax" x86? (4)
¿Cuál es la función del 0x10 con respecto a esta instrucción LEAL? ¿Es una multiplicación o adición o es algo más?
leal 0x10(%ebx), %eax
¿Alguien puede aclarar? Este es un ensamblador x86 en una caja Linux.
El nombre completo es el "Dirección efectiva de carga" y hace exactamente esto: Hace un cálculo de dirección.
En su ejemplo, el cálculo de la dirección es muy simple, porque simplemente agrega un desplazamiento a ebx y almacena el resultado en eax:
eax = ebx + 0x10
lea puede hacer mucho más. Puede agregar registros, multiplicar registros con las constantes 2, 4 y 8 para cálculos de direcciones de palabras, números enteros y dobles. También puede agregar un desplazamiento.
Tenga en cuenta que lea es especial en la forma en que nunca modificará los indicadores, incluso si lo usa como una simple adición como en el ejemplo anterior. Los compiladores a veces explotan esta característica y reemplazan una adición por una lea para ayudar al programador. No es raro ver instrucciones para hacer aritmética simple en código compilado por esa razón.
Para agregar a la respuesta de Nils,
Como repaso, el modo de direccionamiento en el ensamblador IA32 generalmente tiene la forma:
IO (Rb, Ri, s), donde:
IO = Desplazamiento Inmediato
Rb = Base Register
Ri = Índice de registro
s = Factor de escala {1, 2, 4, 8}
Entonces, la dirección efectiva se calcula como * IO + [Eb] + [Ei] s
leal se parece a otras instrucciones como movl, pero es un poco especial. En lugar de leer desde la fuente hasta el destino, copia la dirección efectiva de la fuente en el destino.
Por lo tanto, puede usarse para generar punteros para referencias de memoria posteriores, y también para operaciones aritméticas básicas, como señaló Nils.
Por ejemplo:
deja que register% edx contenga un valor de x
leal 1 (% edx,% edx, 8),% eax
cargará la dirección efectiva de 1 + x + 8 * x = 1 + 9x para registrar% eax.
En esencia, la operación:
fuente leal , destino => destino = dirección de la fuente
Si está familiarizado con C, es el equivalente de:
char * b = & a;
donde la dirección de char a está asignada al puntero char b
más ejemplos:
Deje que register% eax mantenga el valor x, y registre% ecx hold value y
leal (% eax,% ecx, 4),% edx asignará el valor x + 4y para registrar% edx
leal 0xB (,% ecx, 5),% edx asignará el valor 0xB + 5y = 11 + 5y a% edx
leal (% eax,% eax, 2),% eax asignará el valor 3x para registrar% eax
Espero que esto ayude
lea
significa "dirección efectiva de carga"; es una forma de utilizar los modos de dirección sofisticados del conjunto de instrucciones IA32 para hacer aritmética. El sufijo l
es una forma de distinguir el tamaño de los operandos de instrucción en la sintaxis de GNU como, que tiene en su cuadro de Linux.
Entonces, en resumen, sí, es una especie de instrucción de suma. También puede manejar multiplicaciones por 2, 4 u 8 al mismo tiempo.
Consulte también esta pregunta relacionada (donde están usando la sintaxis de Intel para analizar la misma instrucción):
GNU como 2.18 documentos
https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html
AT & T: -4 (% ebp), Intel: [ebp - 4]
y luego la sintaxis de Intel se explica por sí misma.
Más importante aún, los documentos también explican el caso general:
Una referencia de memoria indirecta sintaxis Intel de la forma
section:[base + index*scale + disp]
se traduce a la sintaxis de AT & T
section:disp(base, index, scale)
donde la base y el índice son los registros de índice y base de 32 bits opcionales, disp es el desplazamiento opcional, y la escala, tomando los valores 1, 2, 4 y 8, multiplica el índice para calcular la dirección del operando
Las cosas se vuelven un poco complicadas en AT & T cuando omite algunas partes de la dirección, por ejemplo, -4(%ebp)
, pero con los ejemplos en los documentos podemos deducir fácilmente todos los casos de sintaxis.
Para comprender realmente lo que está sucediendo, le recomiendo que observe cómo se codifican las instrucciones. Este es un buen tutorial: http://www.c-jump.com/CIS77/CPU/x86/lecture.html Cuando vea eso, quedará claro por qué algunas partes de la dirección pueden omitirse, y qué forma compilará a.