                   INTRODUCCION AL ASM: LA INSTRUCCION MOV (I)
                   ===========================================

   La operacin ms bsica que el uP es capaz de realizar es el movimiento de
datos (nmeros) de un lugar a otro. Puede moverlos de un registro a otro, de
un registro a la memoria o de la memoria a un registro.

   La instruccin en lenguaje ensamblador que representa esta operacin se
denomina 'MOV', del ingls 'move', y puede traducirse en muchos cdigos de
operacin distintos en funcin del origen y el destino del dato. La instruccin
MOV tiene dos operandos, que van despus del 'mov' dejando uno o varios separa-
dores entre el 'MOV' y el primer operando (diciendo separadores nos referire-
mos siempre a los espacios - carcter 32d o 20h - y a los tabuladores - carc-
ter 09) y separados por una coma y/o varios separadores. La sintxis es la
siguiente:

		MOV destino,origen

   En esta instruccin 'origen' significa el lugar de donde el uP recoge el
dato a mover y 'destino' el lugar donde lo escribe despus. Estos operandos
pueden ser de muchas formas, y en funcin de la forma de estos se habla del
'modo de direccionamiento', que es el modo en como se accede al destino o al
origen. Podramos dar una larga y tediosa lista de los nombres de todos los
modos de direccionamiento, pero lo que haremos ser ir viendo ejemplos fcil-
mente asimilables, de forma que luego quien quiera pueda aprenderse los nombres
de los distintos modos de direccionamiento.

   Uno de los usos ms sencillos es el de mover un dato de un registro a otro.
Por ejemplo, para mover el dato del registro BX al registro AX escribiramos:

		MOV AX,BX

   El contenido anterior del registro AX se pierde, de manera que el valor del
BX 'pisa' lo que hubiera en el AX. Despus de ejecutarse esta instruccin, los
registros BX y AX contendrn el mismo valor, el contenido anterior del BX.

   De la misma forma, podemos comprender las siguientes instrucciones:

		MOV AX,DS
		MOV ES,AX
		MOV DX,AX
		...

   Hacemos aqu un pequeo inciso para explicar cmo se aaden los comentarios
a los listados en ASM: cuando el ensamblador encuentra un punto y coma (carc-
ter ';'), ignora todos los caracteres hasta que encuentra el final de la lnea
actual. Por tanto, las instrucciones anteriores se pueden comentar:

		MOV AX,DS	; Carga AX con el valor del DS
		MOV ES,AX	; ES = AX
		MOV DX,BX	; DX <- BX

   Esta convencin para los comentarios la aceptan los ensambladores como el
MASM o el TASM, pero tambin lo acepta el DEBUG del MS-DOS (ms adelante
veremos cmo usarlo).

   Retomemos los usos de la instruccin MOV. Otra de las posibilidades es
cargar en un registro directamente un valor. Por ejemplo, podemos inicializar
los registros AX, BX, CX y DX a 1,2,3 y 4 respectivamente con las siguientes
instrucciones:

		MOV AX,1
		MOV BX,2
		MOV CX,3
		MOV DX,4

   Un punto que me gustara destacar respecto al uso 'MOV reg,valor' es que
los registros de segmento no se pueden cargar directamente. Es decir, no
existe cdigo de operacin para la instruccin

		MOV DS,0040h

   Sino que hay que hacerlo necesariamente por medio de otro registro:

		MOV AX,0040h
		MOV DS,AX

   Otro aspecto que querra comentar respecto a la instruccin 'MOV': el
cdigo de operacin de las instrucciones de transferencia entre registros in-
corpora algunos campos que especifican de qu registro a qu registro se mueve
el dato. Pero en estas ltimas instrucciones, el dato que se quiere cargar en
el registro va con el propio cdigo de operacin. Es decir, el 8086 espera
encontrar el valor a guardar inmediatamente despus de lo que constituye el
verdadero 'opcode' (o cdigo de operacin), que es el que identifica a la ins-
truccin y no depende del valor a guardar. Por eso, las primeras instrucciones
(MOV AX,BX; etc...) slo ocupan dos bytes (ambos forman el cdigo de operacin
de la instruccin), mientras que las otras (MOV AX,1; etc...) ocupan dos o tres
bytes. A qu se debe esta diferencia del tamao? Se debe a una caracterstica
del 8086 de la que todava no hemos hablado:

   Cuando se dise el 8086, se penso (hicieron bien) que en algunos casos
interesara acceder por separado al byte alto y byte bajo que componen los
registros, de manera que podamos operar con valores del tamao de un byte. Por
tanto, se incluyeron instrucciones que en lugar de operar sobre los registros
de 16 bits completos operaban sobre los bytes que los componen. Esta subdivi-
sin slo se hizo para los cuatro registros de propsito general, y en ASM se
identifican con los siguientes nombres:

	AX	->	AH (byte alto) y AL (byte bajo)
	BX	->	BH ( "    "  ) y BL ( "    "  )
	CX	->	CH ( "    "  ) y CL ( "    "  )
	DX	->	DH ( "    "  ) y DL ( "    "  )

   As, las siguientes instrucciones tambin tienen su correspondiente
cdigo de operacin. Espero que su funcin resulte obvia:

		MOV AL,BL
		MOV CH,CL
		MOV DL,5
		MOV BH,2

   Es necesario dejar claro que los registros AL y AH, por ejemplo, son parte
del propio AX y por tanto no son independientes de ste. Por tanto, tras
ejecutar las siguientes instrucciones:

		MOV AX,0FFFFh
		MOV AL,00
		MOV AH,00

   El registro AX valdr 0000, ya que tanto su byte alto como su byte bajo se
han puesto a cero.

   El tamao de la instruccin 'MOV reg,valor', volviendo a donde lo dejamos,
depende del tamao del registro que se modifique. Si se modifica un registro de
16 bits, el dato que viene a continuacin debe ser de ste tamao, por lo que
adems del byte con el opcode necesitamos otros dos con el valor, por lo que el
total es de tres bytes. En cambio, en una instruccin como 'MOV AL,00' slo es
necesario un byte con el valor despus del opcode, por lo que el tamao total
de la instruccin es de dos bytes.

   Otro de los posibles usos de la instruccin MOV es el de cargar un registro
con el contenido de una posicin de memoria. El operando destino indicar el
registro en el que se debe almacenar el valo, mientras que el operando origen
ser la direccin de la que se debe cargar el dato. Para indicar que lo que se
quiere cargar es el valor contenido en la posicin de memoria dada, se encierra
la direccin entre corchetes:

		MOV AL,[0000]	; Carga el valor de la posicin cero en AL,
				; a diferencia de la siguiente instruccin,
		MOV AH,00	; que carga el VALOR 0 en AH

   Ya que con los 16 bits que damos como direccin de memoria (no se pueden
dar los 20 bits completos) no se puede generar la direccin completa, se usa
el registro DS para formarla como vimos en el captulo anterior. Ms adelante
veremos cmo se puede especificar que se use otro registro.

   Esto se denomina 'direccionamiento indirecto', en el que el operando es una
posicin de memoria de la que cargar el dato en lugar del valor a cargar. A
proposito, el dar directamente el valor se denomina 'direccionamiento
inmediato'.

   Si el registro indicado es de 16 bits, se carga el byte bajo de la direccin
dada y el byte alto de la siguiente (ordenamiento Intel, recordis?).

		MOV AX,[0000]	; Carga el valor de la posicin 0 en AL
				; y el de la posicin 1 en AH

   Al igual que se puede cargar un registro con el contenido de una posicin
de memoria, se puede almacenar el contenido de un registro en una posicin de
memoria. La instruccin, como habris adivinado, queda as:

		MOV [0000],AX	; Almacena AL en la pos. 0 y AH en la pos. 1
		MOV [0505h],AL	; Almacena AL en la pos 0505h

   Aunque as podemos acceder a posiciones de memoria determinadas, a menudo
interesa acceder a la posicin de memoria indicada por un registro. En el caso
del 8086, es posible acceder a la posicin de memoria apuntada por BX, tanto
para lectura como para escritura, de esta forma:

		MOV AL,[BX]	; Carga en AL el valor almacenado en la
				; posicin de memoria dada por BX
		MOV [BX],DX	; Almacena DL en la posicin dada por BX,
				; y DH en la posicin siguiente

   Para darnos ms posibilidades, los cdigos de operacin del 8086 incluyen
un acceso a memoria a una posicin nn bytes ms adelante de la dada por BX,
todo en una sola instruccin:

		MOV AX,[BX+15d]	; Carga los dos bytes de la posicin apuntada
				; por BX ms 15 y de la siguiente
		MOV [BX-12d],DL	; Almacena DL en la direccin dada por BX
				; menos 12

   Este valor que se suma a BX antes de generar el acceso a memoria viene, de
la misma manera que el valor en el direccionamiento inmediato, inmediatamente
despus del cdigo de operacin, y forma parte de la instruccin. Si el valor
del desplazamiento est entre -128d y +127d, es decir, 'cabe' en un byte
(ya que el desplazamiento se interpreta como entero con signo), se genera una
instruccin un byte ms corta que si el valor necesita una palabra entera. De
todas formas, el desplazamiento (el valor que se suma a BX) nunca puede salirse
de una palabra.

   Hemos visto que el acceso a memoria por medio de un registro lo hacemos
siempre con el BX. De hecho, no existen cdigos de operacin para acceder con
el AX, el CX y el DX. Por tanto las siguientes instrucciones no las acceptar
el ensamblador:

		MOV BX,[AX]	; MAL
		MOV CL,[DX]	; MAL

   Y ahora, viendo esta limitacin de registros para apuntar a memoria, llega
el momento de introducir otros dos registros: el SI ('Source Index') y el DI
('Destination Index'). Estos registros admiten todos los modos de direcciona-
miento que hemos visto, y adems algunos que todava no conocemos. La nica
diferencia es que no se puede acceder por separado a los bytes alto y bajo, por
lo que siempre usaremos los registros 'enteros'.

   Por ejemplo, podemos hacer cosas como:

		MOV AX,0040h
		MOV DS,AX	; Segmento de datos a partir de 00400h absoluta
		MOV SI,2
		MOV AX,[SI]	; Carga el byte almacenado en 00402h absoluta
				; en AL, y el de 00403h en AH

   Bueno, en el siguiente captulo seguiremos con ms usos de la instruccin
MOV (ms modos de direccionamiento) y veremos cmo experimentar con el DEBUG.
Pensaba explicar todo esto en un slo captulo, pero se me alarga demasi.

   Salut!!! :-)

   Jon