- Modos de direccionamiento
-
Los llamados modos de direccionamiento son las diferentes maneras de especificar en informática un operando dentro de una instrucción en lenguaje ensamblador.
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 direccionamiento 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.
Advertencia
Tenga en cuenta que no existe una forma generalmente aceptada de nombrar a los distintos modos de direccionamiento. En particular, los distintos autores y fabricantes de equipos pueden dar nombres diferentes para el modo de hacer frente al mismo, o los mismos nombres, a los diferentes modos de direccionamiento. Además, un modo de direccionamiento que en una determinada arquitectura se trata como un modo de direccionamiento, puede representar la funcionalidad que en otra arquitectura está cubierto por dos o más modos de direccionamiento.
El término "modo de direccionamiento" está sujeta a interpretaciones diferentes: o bien "dirección de memoria de modo de cálculo" o "modo de acceso operando". Bajo las instrucciones de la primera interpretación, que no puede leer o escribir de la memoria a la memoria (como "añadir literal de registro"), se considerará que no tienen un "modo de direccionamiento". La segunda interpretación permite para las máquinas tales como VAX, que utilizan bits de modo operando para permitir un operando literal.Sólo la primera interpretación se aplica a las instrucciones tales como "carga efectiva de dirección".
Las instrucciones que aparecen a continuación son meramente representativas a fin de ilustrar los modos de direccionamiento, y no necesariamente reflejan los mnemónicos utilizado por cualquier equipo en particular.
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 código 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 aritméticas no requieren direccionamiento explícito por lo que se ponen como:
- add
- sub
...
¿Por qué? Porque cuando se opera con dos datos en esta arquitectura se sabe que son los dos elementos del tope de la pila:
Ejemplo de una pila
1 2 3 4 5 6 <- pila
top() es 1
ntop() es 2
donde top() representa el tope de la pila y ntop() el siguiente al tope de la pila y son estos argumentos con los que se opera al llamar a una orden en concreto.
Otro 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 propósito general, por ejemplo con órdenes 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.
Cuando el campo de dirección especifica un registro del procesador, la instrucción se dice que está en el modo de registro.
ejemplo:MOV A,#17H
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.
Ejemplo: MOV A,17H
Indirecto
El campo de operando contiene una dirección de memoria, en la que se encuentra la dirección efectiva del operando.
Ejemplo: MOV A,@17H
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.
Ejemplo: MOV A,R0
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
Ejemplo: MOV A,@R0
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 están marcados por el fondo de la pila y el puntero de pila (*SP), El puntero de pila apunta a la última posición ocupada. Así, 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 el contrario, es mucho más 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 parámetros 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 índice
Es similar al anterior, lo único que es el contenido del registro índice 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 índice y una dirección de memoria:
EA = RI+DM RI = registro índice DM = dirección 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 índice según
los siguientes casos:-> Indexado con autopreincremento: Incrementa el registro índice 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 índice 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.
Direccionamiento paginado y direccionamiento segmentado
- Paginado: La memoria se encuentra actualmente dividida en páginas(bloques de igual longitud).
Para obtener las direcciones necesitamos:
- Indicador de página (IP): en un registro específico o de propósito general de la máquina.
- Dirección de la palabra (DP): en el campo CD de la instrucción.
Así, concatenando ambas partes obtenemos la dirección completa.
Segmentado: La memoria se divide en porciones cuyos tamaños son variables. Así, para acceder a ellos se tiene una tabla de segmentos que contiene la dirección del comienzo y del final de cada segmento en memoria.
Usar este tipo de direccionamiento tiene como ventajas que se puede definir segmentos de tamaño arbitrario. Por otro lado, esta misma ventaja, el fraccionamiento de memoria es uno de sus problemas.
Ambos modos de direccionamiento facilitan la multiprogramación gracias a la técnica de la memoria virtual que permite que un proceso no tenga que estar cargado íntegramente en memoria, si no que se cargan distintas páginas del mismo (o segmentos). Si se intenta cargar una página o segmento que no se encuentra en la memoria principal se produce una excepción de falta de página o segmento y se accede a la memoria para cargar la información requerida en la memoria principal.
Algunos modos de direccionamiento obsoletos
Estos modos fueron usados durante 1950-1980 y ya no están disponibles en los computadores modernos. Esta lista no es completa, puesto que hubo otros muchos modos de direccionamiento más, algunos más interesantes y peculiares.
- Indirecto de multinivel de memoria
Si la longitd de palabra era mayor que la dirección, la palabra era referenciada por este direccionamiento indirecto de multinivel, que podía tener una "bandera" para indicar un ciclo indirecto de memoria. Es necesario tener cuidado para asegurar que una cadena de direcciones indirectas no se refiera a ella misma , si lo hiciera, se llegaría a un bucle infinito mientras trata de encontrar la dirección.
El DEC PDP-10 con 18 bits de direccionamiento y palabras de 36 bits permitían este modo de direccionamiento con la posibilidad de usar un registro principal para cada fase.
- Indirecto de memoria con autoincremento
En algunos minicomputadores había normalmente 16 localizaciones especiales de memoria. Cuando se accedía a memoria, la dirección era automáticamente incrementada y decrementada después de su uso. Esto hacía muy fácil acceder a memoria en bucles sin usar ningún registro.
- "Página cero
La familia Motorola 6800 y la MOS Technology 6502 fueron unas familias de pobres microprocesadores CISC. Las instrucciones aritméticas y lógicas estaban casi todas hechas en contra de los valores de memoria. Como resultado, las instrucciones necesitaban incluir una localización de dos bytes en memoria.
Los diseñadores de estos procesadores incluían un "remedio" llamado direccionamiento "página cero". Los 256 bytes iniciales de memoria podían ser accedidos usando un byte o una dirección de memoria indexada. Esto reducía el tiempo de ejecución de las instrucciones un ciclo de reloj. Almacenando datos en esta "region" los programas podían ser más pequeños y más rápidos.
Como resultado, la "página cero" fue usada de forma parecía a un archivo de registro. En muchos sistemas, sin embargo, provocó una gran utilización del área de memoria de la página cero por el sistema operativo y por los usuarios de programas. Esto limitó su uso desde que el espacio libre fue limitado.
- Índice Siguiente Instrucción
El Elliott 503, el Elliott 803, y el Apollo Guidance Computer sólo se utiliza direccionamiento absoluto, y no tenía ningún registro de índice. Por lo tanto, saltos indirectos, o salta a través de registros, no se admiten en el conjunto de instrucciones. En su lugar, puede ser instruido para agregar el contenido de la palabra de la memoria actual a la siguiente instrucción. Adición de un valor pequeño a la siguiente instrucción a ejecutar podría, por ejemplo, cambiar un JUMP 0 en un JUMP 20, creando así el efecto de un salto indexado. Tenga en cuenta que la instrucción se modifica sobre la marcha y se mantiene sin cambios en la memoria, es decir, no es auto-modificar el código.
Direccionamiento absoluto vs Direccionamiento relativo
En esta sección vamos a resaltar las diferencias de estos dos técnicas de direccionamiento y aclarar las ventajas y desventajas que cada una de ellas conlleva.
- Direccionamiento absoluto: Consiste en direccionar una posición de memoria de forma directa, esto es, que la dirección hace referencia directamente a dicha posición sin tener que realizar cálculos adicionales para la EA.
- Direccionamiento relativo: Cuando para direccionar una posición de memoria se hace referencia a otra sobre la cual se especifica un incremento o decremento, es decir, se requiere otro dato para el cálculo de la dirección efectiva.
Generalmente se usan los direccionamientos relativos ya que, al ejecutar un cierto programa se cumple la proximidad espacial y temporal, lo que implica que datos que ya han sido usados o que se encuentran en posiciones cercanas al PC tendrán una alta probabilidad de ser referenciados próximamente. Otras de las ventajas del direccionamiento relativo es que permite los códigos reentrantes y cambiar ciertas direcciones sin tener que volver a compilar el programa. Es también útil porque nunca se sabe en qué posición de memoria se cargará un determinado programa. Por último reduce el número de bits para especificar las direcciones y se facilita la referencia a datos del programa a través de los registros base.
El problema viene cuando queremos referenciar un dato al que no podemos acceder de forma relativa (p.e porque los registros base no puedan alcanzar dicha posición aun con el incremento más grande que podamos darle), en este caso se requiere el direccionamiento absoluto que sí es capaz de acceder, por lo general, a cualquier dirección de memoria.
Modos de direccionamiento secuencial
Ejecución secuencial
+------+ | nop | ejecuta la siguiente instrucción +------+
(Dirección Efectiva PC = dirección de la instrucción siguiente)
El CPU, después de ejecutar una instrucción secuencial, inmediatamente ejecuta la instrución siguiente.
La ejecución secuencial no esta considerada un modo de direccionamiento en algunos computadores.
La mayoría de instrucciones en la mayoría de las arquitecturas de CPU son instrucciones secuenciales. Debido a que la mayoría de las instrucciones son de tipo secuencial, los diseñadores de la CPU a menudo añaden características que deliberadamente sacrifican el rendimiento por un lado, y por otro las instrucciones de la rama de instrucciones a fin de que estas instrucciones secuenciales corran más rápido.
Las ramas condicionales cargan en el PC varios resultados posibles, muchas de las arquitecturas CPU usan algún otro modo de direccionamiento para la "toma" de rama, y la ejecución secuencial para la "no toma" de rama.
Muchas características de las CPU's modernas mantienen la ilusión de que cada instrucción termina antes de que la siguiente comienze, dando resultados finales iguales, a pesar de que no es exactamente lo que sucede internamente.
CPU'S que no utilizan la ejecución secuencial
Las CPU's que no utilizan la ejecución secuencial con un contador de programa son extremadamente raras. En algunos procesadores, en cada instrucción siempre se especifica la dirección de la instrucción siguiente. Esta CPU tiene un puntero de instrucción que sostiene la dirección especificada, pero no tiene un programa completo mostrado. Las CPU's incluyen algunas cajas de ritmos de la memoria, la máquina SECD, y el RTX 32P.
Otras arquitecturas de computación van mucho más allá, trantando de evitar el cuello de botella de von Neumann, usando una variedad de alternativas para el contador de programa.
Ejecución condicional
Algunas arquitecturas de ordenador (por ejemplo, ARM) tienen instrucciones condicionales que en algunos casos puede obviar la nacesidad de saltos condicionales y evitar el lavado de la tubería de la instrucción. Una instrucción tal como "comparar" see utiliza para establecer un código de condición, y las instrucciones posteriores incluyen una prueba de que el código de condición para ver si se cumplen o se ignoran.
Salto
+------+-----+-----+ |skipEQ| reg1| reg2| Salta a la siguiente instrucción si reg1=reg2 +------+-----+-----+
(EA PC = dirección de la instrucción siguiente + 1)
Saltar abordar puede ser considerado como un tipo especial de modo de direccionamiento relativo al PC con un fijo "una" compensación. Al igual que en PC direccionamiento relativo, algunas CPU's tienen versiones de este modo de direccionamiento que sólo se refieren a un registro ( "saltar si REG1==0") o no hay registros, de manera implícita, referente a algunos bits previamente establecidos en el registro del estado. Otras CPU's tienen una versión que selecciona un byte específico de prueba ("saltar si el bit 7 de reg12 es 0").
A diferencia de todas las ramas condicinales, un "salto" no necesita instrucciones para vaciar la tubería de la instrucción, a pesar de que puede necesitarlas para hacer que la siguiente instrucción sea ignorada.
Modos simples de direccionamiento de datos
Registro
+------+-----+-----+-----+ | mul | reg1| reg2| reg3| reg1 := reg2 * reg3; +------+-----+-----+-----+
Este "modo de direccionamiento" no tiene una dirección efectiva y no se considera como un modo de dirección en algunas computadoras.
En este ejemplo, todos los operandos están en registros, y el resultado se coloca en un registro.
Base mas desplazamiento y variaciones
Muchas veces nos referimos a él como "base más desplazamiento"
+------+-----+-----+----------------+ | load | reg | base| offset | reg := RAM[base + offset] +------+-----+-----+----------------+
(La dirección efectiva = desplazamiento + contenidos de la base especificada del registro)
El desplazamiento suele ser un valor con signo de 16 bits (aunque la 80386 se expandió a 32 bits).
Si el desplazamiento es cero, esto se convierte en un ejemplo de registro indirecto frente, la dirección efectiva es sólo el valor en el registro de base.
En muchas máquinas RISC, el registro 0 se fija en el valor cero. Si el registro 0 se utiliza como el registro de base, esto se convierte en un ejemplo de direccionamiento absoluto. Sin embargo, sólo una pequeña parte de la memoria se puede acceder (64 kilobytes, si el desplazamiento es de 16 bits).
El desplazamiento de 16 bits puede parecer muy pequeño en relación con el tamaño de la memoria de los equipos actuales (esta es la razón por la 80386 se expandió a 32 bits). Podría ser peor ya que: los sevidores IBM System/360 sólo tienen un signo de 12 bits de desplazamiento. Sin embargo, el principio de localización se aplica en un corto espacio de tiempo, la mayoría de los elementos de datos que un programa quiere acceder están bastante cerca uno del otro.
Este modo de direccionamiento está estrechamente relacionado con el modo de direccionamiento absoluto.
Ejemplo 1: Dentro de una subrutina, un programador estará principalmente interesados en los parámetros y las variables locales, que rara vez superan 64 KB, para lo que un registro base es suficiente. Si esta rutina es un método de clase en un lenguaje orientado a objetos, entonces se necesita un segundo registro base con punteros en los atributos del objeto actual.
Wikimedia foundation. 2010.