2009-12-06 19 views

Respuesta

62

Hay algunas operaciones que puede solo hacer con DI/SI (o sus contrapartes extendidas, si no aprendió ASM en 1985). Entre ellos están

REP STOSB 
REP MOVSB 
REP SCASB 

que son, respectivamente, operaciones de almacenamiento repetido (= masivo), carga y escaneo. Lo que debes hacer es configurar SI y/o DI para apuntar a uno o ambos operandos, tal vez poner un conteo en CX y luego dejar que se rompa. Estas son operaciones que funcionan en un grupo de bytes a la vez, y ponen la CPU en modo automático. Como no está codificando explícitamente bucles, lo hacen de manera más eficiente (generalmente) que un bucle codificado a mano.

En caso de que se lo pregunte: Dependiendo de cómo configure la operación, el almacenamiento repetido puede ser algo tan simple como perforar el valor 0 en un gran bloque contiguo de memoria; Me parece que MOVSB ​​se utiliza para copiar datos de un búfer (bueno, cualquier grupo de bytes) a otro; y SCASB se utiliza para buscar un byte que coincida con algún criterio de búsqueda (no estoy seguro de si solo está buscando igualdad, o qué – puede buscar :) :)

Eso es más de lo que esas reglas son para .

+5

Consejo de optimización del pasado: * rep stosw * es mucho más rápido que * rep stosb *, por lo que si se copian dos y dos bytes se ajusta con lo que está tratando de hacer, use eso en su código de ensamblaje optimizado a mano de 16 bits x86 ... – Alexander

27

Opcodes como MOVSB ​​y MOVSW que copian eficientemente datos de la memoria apuntada por ESI a la memoria apuntada por EDI. Por lo tanto,

mov esi, source_address 
mov edi, destination_address 
mov ecx, byte_count 
cld 
rep movsb ; fast! 
10

Además de las operaciones de cadena (MOV/INS/STOS/CMPS/SCASB/W/D/Q etc) mencionados en las otras respuestas, quería añadir que también hay más " modernos instrucciones de montaje x 86" que utilizan al menos implícitamente EDI/RDI:

el SSE2 MASKMOVDQU (y la próxima AVX VMASKMOVDQU) instrucción de escritura selectiva bytes de un registro XMM a la memoria apuntada por EDI/RDI.

63

SI = Fuente Índice Índice
DI = Destino

Como otros han indicado, tienen usos especiales con las instrucciones de cadena. Para la programación de modo real, el registro ES segmento debe ser utilizado con DIDS y con SI como en

movsb es:di, ds:si 

SI y DI también se pueden utilizar como registros índice de propósito general. Por ejemplo, el código fuente C

srcp [srcidx++] = argv [j]; 

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 offset por 0x54 (la ubicación de srcp); los corchetes alrededor de la dirección indican indirección.


Aunque no puedo recordar dónde lo vi, pero this confirma la mayor parte de ella, y this (diapositiva 17) otros:

AX = acumulador
DX = palabra doble acumulador
CX = contador
BX = registro base

Parecen registros de propósito general, pero hay una serie de i ntrucciones que (¿inesperadamente?) usan una de ellas, pero ¿cuál? - implícitamente.

3

Además de los registros que se usan para operaciones masivas, son útiles para su propiedad de ser preservados a través de una llamada de función (llamada preservada) en la convención de llamadas de 32 bits. El ESI, EDI, EBX, EBP, ESP se conservan en llamada, mientras que EAX, ECX y EDX no se conservan en la llamada. Los registros conservados en la llamada son respetados por la función de la biblioteca C y sus valores persisten a través de las llamadas a funciones de la biblioteca C.

Jeff Duntemann en su libro de lenguaje ensamblador tiene un código de ensamblaje de ejemplo para imprimir los argumentos de la línea de comandos. El código usa esi y edi para almacenar contadores, ya que no se modificarán con la función de biblioteca C printf. 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

Sección 12.8 ¿Cómo C ve argumentos de 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 o no.

+0

Nunca he escuchado que se use "sagrado" para describir lo que la mayoría de la gente llama "volátil"/"no volátil" , o "guardado en línea" frente a "guardado por el que llama". Me gusta "call-preserved"/"call-clobbered", ya que no implica que realmente se guarden en cualquier lugar. De todos modos, ESI/RSI y EDI/RDI no se conservan en la llamada en el x86-64 System V ABI. –

+0

Además, olvidó enumerar EBP y ESP como llamadas preservadas en las convenciones comunes de llamadas de 32 bits. –

+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 debido a que son especiales para cualquier instrucción. –

Cuestiones relacionadas