¿Cuál es el propósito real y el uso de los registros EDI y ESI en ensamblador?
Sé que se utilizan para operaciones de cadenas para empezar.
¿Alguien también puede dar un ejemplo?
¿Cuál es el propósito real y el uso de los registros EDI y ESI en ensamblador?
Sé que se utilizan para operaciones de cadenas para empezar.
¿Alguien también puede dar un ejemplo?
Respuestas:
Hay algunas operaciones que solo puede hacer con DI / SI (o sus contrapartes extendidas, si no aprendió ASM en 1985). Entre estos se encuentran
REP STOSB
REP MOVSB
REP SCASB
Que son, respectivamente, operaciones de almacenamiento, carga y escaneo repetidos (= masivos). Lo que debe hacer es configurar SI y / o DI para que apunten a uno o ambos operandos, tal vez poner un recuento en CX y luego dejar que rip. Estas son operaciones que funcionan en un montón de bytes a la vez, y ponen la CPU en automático. Debido a que no está codificando bucles explícitamente, hacen lo suyo de manera más eficiente (generalmente) que un bucle codificado a mano.
Por si acaso se lo está preguntando: Dependiendo de cómo configure la operación, el almacenamiento repetido puede ser algo simple como ingresar el valor 0 en un gran bloque contiguo de memoria; MOVSB se usa, creo, para copiar datos de un búfer (bueno, cualquier grupo de bytes) a otro; y SCASB se usa para buscar un byte que coincida con algún criterio de búsqueda (no estoy seguro de si solo está buscando en igualdad, o qué; puedes buscarlo :))
Eso es la mayor parte de lo que son esas reglas.
SI
= Índice de origen
DI
= Índice de destino
Como han indicado otros, tienen usos especiales con las instrucciones de cadena. Para la programación en modo real, el ES
registro de segmento debe usarse con DI
y DS
con SI
como en
movsb es:di, ds:si
SI y DI también se pueden utilizar como registros de índice de propósito general. Por ejemplo, el C
código fuente
srcp [srcidx++] = argv [j];
se compila en
8B550C mov edx,[ebp+0C]
8B0C9A mov ecx,[edx+4*ebx]
894CBDAC mov [ebp+4*edi-54],ecx
47 inc edi
donde ebp+12
contiene argv
, ebx
es j
y edi
tiene srcidx
. Observe que la tercera instrucción usa edi
multiplicado por 4 y agrega ebp
desplazamiento por 0x54 (la ubicación de srcp
); los corchetes alrededor de la dirección indican indirección.
AX
= acumulador = acumulador de
DX
palabra doble
CX
= contador
BX
= registro base
Parecen registros de propósito general, pero hay una serie de instrucciones que (¿inesperadamente?) Utilizan uno de ellos, ¿pero cuál? De forma implícita.
Códigos de operación como MOVSB y MOVSW que copian de manera eficiente datos de la memoria apuntada por ESI a la memoria apuntada por EDI. Así,
mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!
Además de las operaciones de cadena (MOVS / INS / STOS / CMPS / SCASB / W / D / Q, etc.) mencionadas en las otras respuestas, quería agregar que también hay instrucciones de ensamblaje x86 más "modernas" que se usan implícitamente en menos EDI / RDI:
La instrucción SSE2 MASKMOVDQU
(y la próxima AVX VMASKMOVDQU
) escribe bytes de forma selectiva desde un registro XMM a la memoria apuntada por EDI / RDI.
Además de los registros que se usan para operaciones masivas, son útiles por su propiedad de ser preservados a través de una llamada a función (llamada preservada) en la convención de llamadas de 32 bits. ESI, EDI, EBX, EBP, ESP se conservan en llamadas, mientras que EAX, ECX y EDX no se conservan en llamadas. Los registros de llamadas preservadas son respetados por la función de la biblioteca C y sus valores persisten a través de las llamadas a la función de la biblioteca C.
Jeff Duntemann en su libro de lenguaje ensamblador tiene un código ensamblador de ejemplo para imprimir los argumentos de la línea de comandos. El código usa esi y edi para almacenar contadores, ya que la función de biblioteca C printf no los modificará. Para otros registros como eax, ecx, edx, no hay garantía de que no sean utilizados por las funciones de la biblioteca C.
https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025
Consulte la sección 12.8 Cómo ve C los argumentos de la línea de comandos.
Tenga en cuenta que las convenciones de llamadas de 64 bits son diferentes de las convenciones de llamadas de 32 bits, y no estoy seguro de si estos registros se conservan en llamadas o no.