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 :))
Consejo de optimización del pasado: rep stosw es mucho más rápido que rep stosb , por lo que si copiar dos y dos bytes encaja con lo que está tratando de hacer, utilícelo en su código de ensamblaje x86 de 16 bits optimizado a mano ...
Alexander
88
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 ESregistro de segmento debe usarse con DIy DScon SIcomo 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 Ccódigo fuente
donde ebp+12contiene argv, ebxes jy editiene srcidx. Observe que la tercera instrucción usa edimultiplicado por 4 y agrega ebpdesplazamiento por 0x54 (la ubicación de srcp); los corchetes alrededor de la dirección indican indirección.
Aunque no recuerdo dónde lo vi, esto confirma la mayor parte, y esto (diapositiva 17) otros:
AX= acumulador = acumulador de DXpalabra 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.
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.
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.
Nunca escuché "sagrado" usado para describir lo que la mayoría de la gente llama "volátil" / "no volátil", o "salvado de llamadas" versus "salvado de llamadas". Me gusta "call-preserve" / "call-clobbered", ya que no implica que se guarden en ningún lugar. De todos modos, ESI / RSI y EDI / RDI no se conservan en llamadas en el sistema V ABI x86-64.
Peter Cordes
Además, olvidó listar EBP y ESP como llamadas preservadas en las convenciones comunes de llamadas de 32 bits.
Peter Cordes
1
De todos modos, ese es un buen punto. En el código real, es más probable que elija EDI / ESI para algo basado en razones de convención de llamadas que porque sean especiales para cualquier instrucción.
Peter Cordes
Me gusta la llamada preservada. He actualizado la respuesta con lo mismo. Gracias por la reseña.
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
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.
fuente
SI
= Índice de origenDI
= Índice de destinoComo 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 conDI
yDS
conSI
como enSI y DI también se pueden utilizar como registros de índice de propósito general. Por ejemplo, el
C
código fuentese compila en
donde
ebp+12
contieneargv
,ebx
esj
yedi
tienesrcidx
. Observe que la tercera instrucción usaedi
multiplicado por 4 y agregaebp
desplazamiento por 0x54 (la ubicación desrcp
); los corchetes alrededor de la dirección indican indirección.Aunque no recuerdo dónde lo vi, esto confirma la mayor parte, y esto (diapositiva 17) otros:
AX
= acumulador = acumulador deDX
palabra dobleCX
= contadorBX
= registro baseParecen registros de propósito general, pero hay una serie de instrucciones que (¿inesperadamente?) Utilizan uno de ellos, ¿pero cuál? De forma implícita.
fuente
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í,
fuente
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 AVXVMASKMOVDQU
) escribe bytes de forma selectiva desde un registro XMM a la memoria apuntada por EDI / RDI.fuente
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.
fuente