ASM POR AESOFT. (lección 6). -------------------------------------------------------------------- - CODIFICACION DE LAS INSTRUCCIONES EN EL 8086 (continuación lección 5). - MODOS DE DIRECCIONAMIENTO EN EL 8086. -------------------------------------------------------------------- - CODIFICACION DE LAS INSTRUCCIONES EN EL 8086 (continuación lección 5). ----------------------------------------------------------------------- En la lección 5 nos quedamos por descifrar el valor del byte EA en la siguiente instrucción: MOV WORD PTR DS:[7654H],5 ---> C7 06 54 76 05 00 Teníamos claro el primer byte (código de operación) que nunca ofrece problemas de interpretación. Y era obvio también el campo 'desplazamiento' (formado por los bytes 3 y 4), así como el campo 'valor inmediato' (formado por los bytes 5 y 6). Pero ante el segundo byte (byte EA o de direccionamiento) surgía la duda. He estado probando con instrucciones parecidas para ver si se aclaraba el tema. Y como conclusión puedo decir que cuando se direcciona una posición de memoria (como destino) sin ayuda de ningún registro (SI, DI,BX+SI, etc), el byte EA tendrá valor 06. Esto lo digo de modo empírico. No lo he leído en ningún sitio, ni nada por el estilo. Me baso en las pruebas que he estado haciendo para encontrar algún sentido a ese 06. Sinceramente, no sé por el porqué de esta 'peculiaridad'. Por qué se me ocurriría poner este ejemplo! :-) Por ejemplo, si hubiera usado un registro junto con el desplazamiento en esa instrucción habría problema. Veamos cómo quedaría la cosa: * MOV WORD PTR DS:[DI+7654H],5 ---> Introduce el valor 5 (tipo palabra) en la posición de memoria direccionada mediante [DI] + 7654H. Es prácticamente igual que la instrucción anterior, excepto que en ésta, hemos incluido el registro DI para acceder a la posición de memoria oportuna. La codificación de la instrucción quedaría como sigue: MOV WORD PTR DS:[DI+7654H],5 ---> C7 85 54 76 05 00 Estudiemos el 'byte EA' de esta instrucción tan parecida a la anterior: 85h en binario queda como 10000101. El campo MOD con valor 10 indica que se usan 2 bytes para codificar el desplazamiento. Hasta ahora perfecto: 2 bytes para almacenar el desplazamiento 7654h. El campo REG con valor 000, ya que el valor a introducir no está en ningún registro, sino que es un dato inmediato (05) El campo R/M con valor 101, indicando que la dirección final viene dada por [DI] + desplazamiento. Como podemos ver, la codificación de esta instrucción se ajusta a las tablas de codificación que vimos en la lección 5. Veamos algún ejemplo más, para que nos quede más claro: * MOV BYTE PTR [DI+7],0AEH Esta instrucción deposita el valor 0AEH en la posición de memoria apuntada por DI+7, dentro del segmento direccionado por DS. Veamoslo más detalladamente estudiando su codificación: MOV BYTE PTR [DI+7],0AEH ---> C6 45 07 AE En primer lugar tenemos el código de operación C6, que le indica al procesador que se va a transferir un dato inmediato de tipo byte a una posición de memoria. El tercer byte (campo 'desplazamiento') tiene un valor de 7, que es el que hemos indicado en la instrucción. Este valor es el que se sumará a DI para direccionar la posición de memoria deseada. El cuarto byte (campo 'valor inmediato') tiene un valor de AE. Este valor es el que se depositará en la posición de memoria direccionada mediante DI+7. Sólo nos queda estudiar el segundo byte (byte EA o modo de direccionamiento), el cual tiene un valor de 45 (en hexadecimal). Este 45, queda como 01000101 en binario. Tenemos así que el campo MOD tiene un valor de 01. Si miramos en las tablas de codificación (ver lección 5), tenemos que 01 indica que se utiliza un byte para indicar desplazamiento. El campo REG tiene valor 000. Como no hay ningún registro involucrado en la instrucción, este campo no se tiene en cuenta. Por último, el campo R/M tiene como valor, 101. Esto indica que el desplazamiento final estará dado mediante [DI] + desplazamiento. Como vemos, en esta instrucción está totalmente claro cada valor en cada uno de los campos del byte EA o 'modo de direccionamiento'. Un último ejemplo: * MOV WORD PTR [BX+SI+37H],AX Esta instrucción, introduce el valor del registro AX en la dirección de memoria indicada mediante el valor de la suma BX+SI+37H. Dentro del segmento DS, por supuesto. Siempre que no se especifique otro segmento, las transferencias a/desde memoria se harán sobre el segmento DS. Veamos su codificación: MOV WORD PTR [BX+SI+37H],AX ---> 89 40 37 Simplemente 3 bytes para codificar esta instrucción que parece tan complicada. El primer byte (código de operación) tiene el valor 89 (hexadecimal). Este código 89 indica que se va a realizar una transferencia de datos de tipo palabra desde un registro (tamaño palabra) a un destino que puede ser (dependiendo del valor del byte EA): un registro de tamaño palabra o una dirección de memoria. Ya sabemos que el destino se trata de una dirección de memoria porque lo hemos indicado así al teclear la instrucción, pero el procesador no lo sabrá hasta que descifre el valor del byte EA. Este byte EA tiene un valor de 40h, que en binario queda como 01000000 El campo MOD tiene un valor de 01, que indica que se usa 1 byte para codificar el desplazamiento. Sólo es necesario 1 byte para codificar el valor 37h. El campo REG, que aquí tiene valor 000, indica que el registro fuente empleado es AX. El campo R/M con valor 000, indica que la dirección final se consigue mediante la suma: [BX] + [SI] + desplazamiento. Ver tablas en la lección 5. Como vemos aquí también está totalmente claro el valor del byte EA. El tercer byte (campo 'desplazamiento') contiene el valor 37h como hemos indicado en la instrucción. Espero que estos nuevos ejemplos hayan sido ilustrativos. En caso de que aún exista alguna duda acerca de la codificación de las instrucciones, levantad la mano :-))) - MODOS DE DIRECCIONAMIENTO EN EL 8086. -------------------------------------------------------------------- Como ya hemos visto, las instrucciones están codificadas con 0, 1 ó 2 operandos. Estos operandos son cada uno de los campos que puede componer una instrucción ('byte EA', 'desplazamiento' y 'valor inmediato'). Pues bien, las operaciones se realizan entre registros o registros y memoria. Nunca entre memoria y memoria. Si echamos un vistazo al esquema de codificación, nos daremos cuenta del porqué: No hay dos campos para almacenar 2 posiciones diferentes de memoria, mientras que sí que se pueden indicar 2 registros diferentes (uno fuente y otro destino) en una misma instrucción. Existen varios modos de direccionamiento. Esta variedad se ofrece para una mayor comodidad en la programación. Así por ejemplo se puede utilizar el modo directo, cuando se conoce la dirección de la posición de memoria que nos interese. El resto de modos se utilizarán cuando no vayamos a acceder a una dirección de memoria conocida, o cuando nos sea más cómodo por cualquier motivo. * Modos de direccionamiento: Inmediato --------- El dato aparece directamente en la instrucción. Es decir, se indica explícitamente en la instrucción. Ejemplo: MOV AL,0AEH ---> Almacena el valor AE en el registro de tipo palabra (AL). Modo Registro ------------- Cuando en la instrucción se realizan transferencias entre registros del procesador. Ejemplo: MOV AX,BX ---> Introduce el valor de BX en AX. Directo absoluto a memoria -------------------------- Aparece en la instrucción de forma explícita la dirección a la cual se quiere acceder. Esto es, en la codificación de la instrucción podemos encontrar 2 bytes indicando la posición de memoria que se quiere direccionar. Ejemplo: MOV CX,WORD PTR DS:[7777] ---> Introduce el valor almacenado en la posición de memoria 7777 (dentro del registro DS) en el registro de tipo palabra (CX). Directo relativo a un registro base ----------------------------------- Accede a una posición de memoria con la ayuda de un registro base. Estos registros base como ya vimos son BX y BP. La dirección final de la posición de memoria se indicará de la forma: Dirección final = [Registro_Base] + desplazamiento. Donde Registro_Base es o bien BX o bien BP. Ejemplo: MOV AX,BYTE PTR [BX+7] ---> Introduce en AX el valor contenido en la posición de memoria direccionada mediante BX+7. Directo relativo a un registro índice (Indexado) ------------------------------------------------ La dirección se obtiene sumando un desplazamiento (que se indicará en la instrucción) al contenido de un registro índice. Registros índice como ya vimos son: SI y DI. Donde SI se suele utilizar como registro índice fuente. 'Indice fuente' en inglés = 'Source Index' = SI. Obviamente, DI se utilizará como registro índice destino. 'Indice destino' en inglés = 'Destine Index' = DI. La dirección final de la posición de memoria se indicará de la forma: Dirección final = [Registro_Indice] + desplazamiento. Donde Registro_Indice es o bien SI o bien DI. Ejemplo: MOV AX,WORD PTR [SI+7] ---> Introduce en AX el valor contenido en la posición de memoria direccionada mediante SI+7. En realidad, excepto cuando se utilizan los dos registros fuentes en una misma operación (al copiar cadenas de caracteres p.e.), en cuyo caso hay que asignar a SI la dirección de la cadena origen, y a DI hay que asignarle la dirección de la cadena destino... Excepto en este tipo de operaciones (como digo), podemos hacer uso de los registros SI y DI indistintamente al trabajar con direccionamientos. Es decir, que las dos instrucciones siguientes son correctas, y realizan exactamente la misma tarea (siempre que SI y DI tengan el mismo valor): MOV AX,WORD PTR [SI+7] MOV AX,WORD PTR [DI+7] Modos indirectos de direccionamiento ------------------------------------ Si en los dos últimos modos de direccionamiento no se especifica desplazamiento, entonces hablamos de: Modo de direccionamiento indirecto por registro base, Modo de direccionamiento indirecto por registro índice, respectivamente. Ejemplo: MOV AX,BYTE PTR [SI] ---> Introduce en AX el contenido de la posición de memoria direccionada mediante SI. Indexado mediante una base -------------------------- La posición de memoria seleccionada se direcciona aquí mediante cuatro configuraciones posibles. Un registro BX o BP contiene la base y un registro SI o DI contiene el desplazamiento. Además, puede existir un desplazamiento opcional indicado mediante un valor numérico. La dirección final de la posición de memoria se indicará de la forma: Dirección final = [Registro_Base] + [Registro_Indice] + desplazamiento. Donde Registro_Base es o bien BX o bien BP. Donde Registro_Indice es o bien SI o bien DI. Tenemos así las cuatro configuraciones posibles mencionadas: - [BX] + [SI] + desplazamiento - [BX] + [DI] + desplazamiento - [BP] + [SI] + desplazamiento - [BP] + [DI] + desplazamiento Ejemplo: MOV BYTE PTR [BX+SI],AL ---> Introduce el valor del registro AL en la posición de memoria direccionada mediante [BX] + [SI] + desplaz. En todos los modos de direccionamiento, excepto en los dos primeros, se puede indicar un segmento diferente a DS para realizar las operaciones con la memoria. De esta forma, podemos manejar todo el Megabyte de memoria sin necesidad de modificar de valor el registro DS (registro de segmento de datos). Así, podemos utilizar el registro ES cuando queramos acceder a posiciones de memoria que estén fuera de nuestro segmento de datos. Ejemplo: MOV AX,WORD PTR ES:[BX+7] ---> Introduce en AX el valor contenido en la posición de memoria direccionada mediante BX+7, dentro del segmento indicado por ES.