lunes, 2 de septiembre de 2013

modos de direccionamiento


| MODOS DE DIRECCIONAMIENTO |

Los llamados modos de direccionamiento son las diferentes maneras de especificar en informática un operando dentro de una instrucción. Cómo se especifican e interpretan las direcciones de memoria según las instrucciones. Un modo de direccionamiento especifica la forma de calcular la dirección de memoria efectiva de un operando mediante el uso de la información contenida en registros y / o constantes, contenida dentro de una instrucción de la máquina o en otra parte.



-------------------------------------------------------------------------------------------------------------------------------------------

¿CUÁNTOS MODOS DE DIRECCIONAMIENTOS EXISTEN?




Diferentes arquitecturas de computadores varían mucho en cuanto al número de modos de direccionamiento que ofrecen desde el hardware. Eliminar los modos de direccionamiento más complejos podría presentar una serie de beneficios, aunque podría requerir de instrucciones adicionales, e incluso de otro registro. Se ha comprobado que el diseño de CPUs segmentadas es mucho más fácil si los únicos modos de direccionamiento que proporcionan son simples.
La mayoría de las máquinas RISC disponen de apenas cinco modos de direccionamiento simple, mientras que otras máquinas CISC tales como el DEC VAX tienen más de una docena de modos de direccionamiento, algunos de ellos demasiado complejos. El mainframe IBM System/360 disponía únicamente de tres modos de direccionamiento; algunos más fueron añadidos posteriormente para el System/390.
Cuando existen solo unos cuantos modos, estos van codificados directamente dentro de la propia instrucción (Un ejemplo lo podemos encontrar en el IBM/390, y en la mayoría de los RISC). Sin embargo, cuando hay demasiados modos, a menudo suele reservarse un campo específico en la propia instrucción, para especificar dicho modo de direccionamiento. El DEC VAX permitía múltiples operandos en memoria en la mayoría de sus instrucciones, y reservaba los primeros bits de cada operando para indicar el modo de direccionamiento de ese operando en particular.
Incluso en computadores con muchos modos de direccionamiento, algunas medidas realizadas a programas indican que los modos más simples representan cerca del 90% o más de todos los modos de direccionamiento utilizados. Dado que la mayoría de estas medidas son obtenidas a partir de códigos de alto nivel generados a partir de compiladores, nos da una idea de las limitaciones que presentan los compiladores que se utilizan.


-------------------------------------------------------------------------------------------------------------------------------------------

TIPOS DE DIRECCIONAMIENTO





Implícito: En este modo de direccionamiento no es necesario poner ninguna dirección de forma explícita, ya que en el propio codigo de operación se conoce la dirección del (de los) operando(s) al (a los) que se desea acceder o con el (los) que se quiere operar.
Supongamos una arquitectura de pila, las operaciones aritmeticas no requieren direccionamiento explícito por lo que se ponen como:
add
subUn ejemplo de este tipo de direccionamiento lo podemos encontrar en la arquitectura de acumulador (AC) donde siempre hay un parámetro implícito y este es el AC. Para finalizar y dejar este modo de direccionamiento generalizado para las arquitecturas más usuales, remarcamos que también podemos encontrarlo en la arquitectura con registros de próposito general, por ejemplo con ordenes como setc, que pone a 1 el registro c (acarreo).
Inmediato: En la instrucción está incluido directamente el operando.
En este modo el operando es especificado en la instrucción misma. En otras palabras, una instrucción de modo inmediato tiene un campo de operando en vez de un campo de dirección. El campo del operando contiene el operando actual que se debe utilizar en conjunto con la operación especificada en la instrucción. Las instrucciones de modo inmediato son útiles para inicializar los registros en un valor constante.




Directo:El campo de operando en la instrucción contiene la dirección en memoria donde se encuentra el operando.
En este modo la dirección efectiva es igual a la parte de dirección de la instrucción. El operando reside en la memoria y su dirección es dada directamente por el campo de dirección de la instrucción. En una instrucción de tipo ramificación el campo de dirección especifica la dirección de la rama actual.
Con este tipo de direccionamiento, la dirección efectiva es contenida en la misma instrucción, tal como los valores de datos inmediatos que son contenidos en la instrucción. Un procesador de 16 bits suma la dirección efectiva al contenido del segmento de datos previamente desplazado en 4 bits para producir la dirección física del operando.




Indirecto:El campo de operando contiene una dirección de memoria, en la que se encuentra la dirección efectiva del operando.



Absoluto: El campo de operando contiene una dirección en memoria, en la que se encuentra la instrucción.
De registro: Sirve para especificar operandos que están en registros.


Indirecto mediante registros: El campo de operando de la instrucción contiene un identificador de registro en el que se encuentra la dirección efectiva del operando. En este modo el campo de la dirección de la instrucción da la dirección en donde la dirección efectiva se almacena en la memoria. El control localiza la instrucción de la memoria y utiliza su parte de dirección para accesar la memoria de nuevo para leer una dirección efectiva. Unos pocos modos de direccionamiento requieren que el campo de dirección de la instrucción sea sumado al control de un registro especificado en el procesador. La dirección efectiva en este modo se obtiene del siguiente cálculo:
Dir. efectiva = Dir. de la parte de la instrucción + Contenido del registro del procesador




De desplazamiento: Combina el modo directo e indirecto mediante registros
De pila: Se utiliza cuando el operando está en memoria y en la cabecera de la pila. Este direccionamiento se basa en las estructuras denominadas Pila(tipo LIFO), las cuales estan marcados por el fondo de la pila y el puntero de pila (*SP), El puntero de pila apunta a la última posición ocupada. Asi, como puntero de direccionamiento usaremos el SP. El desplazamiento más el valor del SP nos dará la dirección del objeto al que queramos hacer referencia. En ocasiones, si no existe C. de desplazamiento solo se trabajara con la cima de la pila. Este tipo de direccionamiento nos aporta flexibilidad pero por contra, es mucho mas complejo que otros tipos estudiados más arriba.
Respecto a un registro base: Este modo de direccionamiento es muy usado por los ensambladores cuando se llaman a las funciones (para acceder a los parametros apilados en la pila, valga la redundancia). Consiste, al igual que el indirecto a través de registro, en calcular la EA (Effective Address) como la suma del contenido del registro base y un cierto desplazamiento (u offset) que siempre será positivo. Esta técnica permite códigos reentrantes y acceder de forma fácil y rápida a posiciones cercanas de memoria.

EA = RB+offset
RB = registro base
offset = desplazamiento
-> RB se comporta como una dirección de memoria a la que se le sumará el desplazamiento

Respecto a un registro indice: Es similar al anterior, lo único que es el contenido del registro indice el que indica el desplazamiento que se produce a partir de una dirección de memoria que se pasa también como argumento a la orden que utiliza este modo de direccionamiento. Aunque en esencia son dos modos equivalentes. La EA se calcula como la suma del contenido del registro indice y una dirección de memoria:

EA = RI+DM
RI = registro indice
DM = direccion de memoria
-> RI se comporta como un offset

Indexado respecto a una base: Se trata de una combinación de los dos anteriores y consiste en calcular la dirección efectiva como:

EA = RI+RB+DM
-> Las siglas significan lo mismo que en el caso anterior

Respecto al contador de programa: Consiste en dirección una posición de memoria usando como registro base al contador de programa (PC), el funcionamiento es análogo al direccionamiento respecto a registro base con la salvedad de que, en este caso, el offset puede ser también negativo.

Indexado con autoincremento/autodecremento: Es un modo de direccionamiento análogo al indexado, explicado anteriormente. La única diferencia es que permite un incremento o decremento de la dirección final o el registro indice según los siguientes casos:

-> Indexado con autopreincremento: Incrementa el registro indice primero (se incrementa un valor, según el tamaño del objeto direccionado) y luego calcula la EA al igual que el direccionamiento indexado.
-> Indexado con autoposincremento: Calcula la dirección efectiva y después incrementa esta.
-> Indexado con autopredecremento: Decrementa el registro indice y después calcula la dirección efectiva.
-> Indexado con autoposdecremento: Calcula la dirección efectica y después decrementa esta.

Instrucción de salto con direccionamiento absoluto: Consiste en cargar en el PC el valor que se especifica en la orden de salto, p.e:

jmp 0xAB ----> Carga 0xAB en PC
Instrucción de salto con direccionamiento relativo: Es parecida a la especificada anteriormente la diferencia es que el salto es relativo al PC, pongamos un ejemplo: Supongamos que PC vale = 0x0A, si nosotros interpretamos la instrucción jr +03, saltaremos tres posiciones posteriores a PC (también podría ser -03 y serían posiciones anteriores). Pero, ¡cuidado! si esa instrucción estaba en la posición 0x0A la dirección de PC a incrementar será la inmediatamente posterior (ya que PC se incrementa automáticamente después de leer la instrucción), por lo que quedaría:

PC = 0x0B ---> nuevo PC = 0x0B+0x03 = 0x0E, con lo que el PC quedaría como 0x0E.

-------------------------------------------------------------------------------------------------------------------------------------------

MODALIDADES DE DIRECCIONAMIENTO





Direccionamiento directo por registro: Se mencionó anteriormente que el campo de dirección de una instrucción puede especificar una palabra de memoria o un registro M procesador. Cuando se da este último caso se dice que el operando está especificado con direccionamiento directo por registro, en tal caso, el operando reside en uno de los registros del procesador que es seleccionado por un campo de registro de k bits en la instrucción. Un campo de k bits puede especificar uno de 2k registros. Este modo es típico de los ordenadores con organización de registros de uso general.

Las ventajas de este modo son:


El acceso a los registros es muy rápido, por tanto el direccionamiento por registro debe usarse en las variables que se usen con más frecuencia para evitar accesos a memoria que son más lentos, un ejemplo muy típico del uso de este direccionamiento son los índices de los bucles.
El número de bits necesarios para especificar un registro es mucho más pequeño que el necesario para especificar una dirección de memoria, esto es debido a que el número de registros del procesador es muy pequeño comparado con el número de direcciones de memoria. Sin embargo, hay que tener en cuenta que en los ordenadores modernos el número de registros ha aumentado considerablemente.
Direccionamiento inmediato (o literal): En este modo es el operando el que figura en la instrucción no su dirección. En otras palabras el campo de operando contiene él mismo, sin transformación alguna, la información sobre la que hay que operar. Este modo es útil para inicializar registros o palabras de memoria con un valor constante.
Direccionamiento directo (o absoluto): Este es el modo de direccionamiento más sencillo. El campo de dirección no necesita transformación alguna para dar la dirección efectiva, es decir la función que transforma el campo de operando en la dirección efectiva es la identidad. Esto significa que el campo de operando es ya la dirección efectiva.
Este direccionamiento sólo se usa en ordenadores pequeños en que el programa siempre se sitúa en la misma zona de memoria ya que dificulta la relocalización de los programas, es decir que el código de los programas no dependa de su situación en memoria. Ordinariamente este modo sólo se usa para acceder a direcciones del sistema que normalmente se refieren a operaciones de entrada y salida ya que estas direcciones no dependen del programa.
Direccionamiento indirecto: En este modo el campo de operando de la instrucción indica la localización de la dirección efectiva del operando. El modo de direccionamiento indirecto puede adquirir diferentes formas según cuál sea el lugar donde se encuentre la dirección del operando. En general, todos los modos de direccionamiento tienen su versión indirecta que añade un eslabón más a la cadena del direccionamiento. Por ejemplo existe el direccionamiento indirecto por registro, en el que el registro especificado contiene la dirección del operando, no el operando mismo.
Este direccionamiento es útil cuando se trabaja con punteros ya que los punteros son variables que contienen las direcciones de los operandos, no los operandos mismos.
Direccionamiento relativo: Hay algunos modos de direccionamiento en que se hace uso de una propiedad muy generalizada de los programas denominada localidad de referencia, esta propiedad consiste en que las direcciones referenciadas por los programas no suelen alejarse mucho unas de otras y, por tanto, suelen estar concentradas en una parte de la memoria. Estas consideraciones nos llevan a la conclusión de que no es necesario utilizar todos los bits de la dirección de memoria en el campo de operando, basta utilizar los bits precisos para cubrir la parte de memoria donde estén incluidas las direcciones a las que el programa hace referencia. Esto puede hacerse tomando corno referencia un punto de la memoria y tomando como campo de operando la diferencia entre ese punto y la dirección efectiva del operando. La dirección que se toma como punto de referencia puede residir en un registro de la CPU y, por tanto, sumando el contenido de ese registro con el campo de operando obtendremos la dirección efectiva. Hay varios direccionamientos basados en esta técnica que reciben diferentes nombres dependiendo de cuál sea el registro en el que radica la dirección tomada como referencia. Todos ellos podrían catalogarse como direccionamientos relativos a un registro.
El direccionamiento denominado habitualmente relativo toma como valor de referencia el registro contador de programa. Cuando se usa este modo de direccionamiento, el campo de operando consiste en un número (normalmente con signo) que expresa la diferencia entre la dirección del dato y la dirección siguiente a la instrucción en curso (contenida en el contador de programa). Si el campo de operando, llamado en este caso desplazamiento u offset, es positivo el operando residirá en una dirección posterior a la de la instrucción y si es negativo, en una dirección anterior.
Este modo de direccionamiento es usado muy frecuentemente en programas cuyo código deba ser independiente de la posición de memoria donde estén situados (programas relocalizables) ya que el desplazamiento es independiente de la localización del programa. También se usa con mucha frecuencia en instrucciones de bifurcación.
Los apartados siguientes se refieren a diferentes versiones de direccionamientos relativos a registros.-------------------------------------------------------------------------------------------------------------------------------------------

PILA




Aparte de los componentes de la arquitectura presentados en las secciones anteriores, la mayor parte de procesadores ofrecen la infraestructura necesaria para manipular una estructura de datos organizada y almacenada en memoria que se denomina “la pila”.
La pila es una zona de la memoria sobre la que se pueden escribir y leer datos de forma convencional. Esta zona tiene una posición especial que se denomina “la cima de la pila”. El procesador contiene dos instrucciones de su lenguaje máquina para realizar las operaciones de “apilar” y “desapilar” datos de la pila. Los datos que se pueden apilar y desapilar, en el caso del Intel Pentium son siempre de tamaño 4 bytes.

EJECUCION DE INSTRUCCIONES DE PILA




El que la dirección de la pila esté contenida en un registro de propósito general permite que su contenido sea manipulado como cualquier otro registro. Un programa, por tanto, puede leer y escribir cualquier valor de %esp, tan sólo se debe tener en cuenta que el procesador obtiene de ese registro la dirección de memoria necesaria para ejecutar las instrucciones push y pop.
Supóngase que se ha depositado un cierto dato en la pila mediante la instrucción push y que se encuentra, por tanto en la cima. La instrucción pop deposita ese valor en el lugar especificado pero, ¿es posible ejecutar la instrucción pop sin ningún operando?. En otras palabras, la operación que se quiere ejecutar no es la de copiar el dato de la cima, sino simplemente corregir el valor de la cima al igual que haría pop pero sin depositar el dato en ningún lugar. La instrucción pop, por definición, debe incluir un único operando, con lo que no se puede utilizar para hacer esta operación.
La solución se deriva del hecho de que esp. La instrucción ADD $4, esp su valor incrementado en cuatro unidades. El efecto que esta instrucción tiene sobre la pila es el deseado. La siguiente instrucción asume que la cima está en la nueva posición contenida en %esp.

INSTRUCCIONES DE PILA




La pila es un segmento que es de suma utilidad en estos microprocesadores En él se almacenan valores temporales como las variables locales de las funciones, o las direcciones de retorno de éstas. Una función no es más que una subrutina, o un fragmento de código al que se le llama generalmente varias veces desde el programa principal, o desde una función jerárquicamente superior. Cuando se llama a una función se hace un mero salto al punto donde empieza ese código. Sin embargo esa subrutina puede ser llamada desde distintos puntos del programa principal, por lo que hay que almacenar en algún sitio la dirección desde donde se hace la llamada, cada vez que esa llamada tiene lugar, para que al finalizar la ejecución de la función se retome el programa donde se dejó. Esta dirección puede almacenarse en un sitio fijo (como hacen algunos microcontroladores), pero eso tiene el inconveniente de que si esa función a su vez llama a otra función (¡o a sí misma!) podemos sobreescribir la dirección de retorno anterior, y al regresar de la segunda llamada, no podríamos volver desde la primera. Además, es deseable que la función guarde los valores de todos los registros que vaya a usar en algún sitio, para que el que la llame no tenga que preocuparse de ello (pues si sabe que los registros van a ser modificados, pero no sabe cuáles, los guardará todos por si acaso). Todas estas cosas, y algunas más, se hacen con la pila.
El segmento de pila está indicado por SS, y el desplazamiento dentro del segmento, por SP. Cuando arranca el programa, SP apunta al final del segmento de pila. Para almacenar información en la pila se decrementa SP para que apunte un poco más arriba y se copia a esa posición de memoria, SS:SP. Para sacarlo, copiamos lo que haya en SS:SP a nuestro destino, e incrementamos el puntero.
Como con todo lo que se hace con frecuencia, hay dispuestas instrucciones propias para el manejo de la pila. Las dos básicas son PUSH origen (empujar) y POP destino (sacar). La primera decrementa el puntero de pila y copia a la dirección apuntada por él (SS:SP) el operando origen (de tamaño múltiplo de 16 bits), mientras que la segunda almacena el contenido de la pila (elemento apuntado por SS:SP) en destino y altera el puntero en consecuencia. Si el operando es de 16 bits se modifica en 2 unidades, de 32 en 4, etc. Lo que se incrementa/decrementa es siempre SP, claro, porque SS nos indica dónde está ubicado el segmento de pila. La instrucción ret size se utiliza para recuperar de la pila los valores de IP o de CS e IP dependiendo del caso. Al salir de un procedimiento es necesario dejar la pila como estaba; para ello podemos utilizar la instrucción pop, o bien ejecutar la instrucción ret size donde size es el número de posiciones que deben descartarse de la pila.

No hay comentarios:

Publicar un comentario