assembly x86 instructions mov

assembly - Montaje: MOVING entre dos direcciones de memoria.



x86 instructions (5)

Estoy tratando de aprender ensamblaje (así que ten paciencia) y obtengo un error de compilación en esta línea:

mov byte [t_last], [t_cur]

El error es

error: invalid combination of opcode and operands

Sospecho que la causa de este error es simplemente que no es posible que una instrucción de movimiento se mueva entre dos direcciones de memoria, pero media hora de búsqueda en Google y no he podido confirmar esto, ¿es este el caso?

Además, suponiendo que tengo razón, significa que necesito utilizar un registro como punto intermedio para copiar la memoria:

mov cl, [t_cur] mov [t_last], cl

¿Cuál es el registro recomendado para usar (o debo usar la pila en su lugar)?


Es realmente simple en 16 bits, solo haz lo siguiente:

push di push si push cx mov cx,(number of bytes to move) lea di,(destination address) lea si,(source address) rep movsb pop cx pop si pop di

Nota: los pushs y pops son necesarios si necesita guardar el contenido de los registros.


Eso es correcto, el código de máquina x86 no puede codificar una instrucción con dos operandos de memoria explícitos (direcciones arbitrarias especificadas en [] )

¿Cuál es el registro recomendado?

Cualquier registro que no necesite guardar / restaurar.

En todas las convenciones de llamadas principales de 32 y 64 bits, EAX, ECX y EDX están bloqueados, por lo que AL, CL y DL son buenas opciones. En el modo de 64 bits, SIL, DIL, r8b, r9b, etc., también son opciones de búsqueda, pero requieren un prefijo REX en el código de la máquina, por lo que hay una pequeña razón de tamaño de código para evitarlos.

En general, evite escribir AH, BH, CH o DH por razones de rendimiento, a menos que haya leído y comprendido los siguientes enlaces y las dependencias falsas o las paradas de combinación de registros parciales no serán un problema o sucederán en su código. .

(o debo usar la pila en su lugar)?

En primer lugar, no puede insertar un solo byte en absoluto, por lo que no hay forma de que pueda hacer un byte de carga / byte desde la pila. Para una palabra, dword o qword (dependiendo del modo de CPU), puede push [src] / pop [dst] , pero eso es mucho más lento que copiar a través de un registro. Introduce una latencia de reenvío de almacenamiento de almacenamiento / recarga adicional antes de que los datos puedan leerse desde el destino final, y toma más uops.

A menos que en algún lugar de la pila esté el destino deseado y no pueda optimizar esa variable local en un registro, en cuyo caso, push [src] está bien para copiarlo allí y asignarle espacio de pila.

Consulte https://agner.org/optimize/ y otros enlaces de rendimiento x86 en la etiqueta wiki x86


Sólo quiero hablar de "barrera de la memoria" con usted. En c codigo

a = b;//Take data from b and puts it in a

sería ensamblado para

mov %eax, b # suppose %eax is used as the temp mov a, %eax

El sistema no puede garantizar la atomicidad de la asignación. Por eso necesitamos un rmb (leer barrera)


También hay un comando MOVS para mover datos de la memoria a la memoria:

MOV SI, OFFSET variable1 MOV DI, OFFSET variable2 MOVS


Tu sospecha es correcta, no puedes pasar de la memoria a la memoria.

Cualquier registro de propósito general hará. Recuerde PULSAR el registro si no está seguro de lo que hay dentro y restablecerlo una vez hecho.