La memoria y el computador

En esta entrada, se pretende atrapar al lector en la manera que el lenguaje ensamblador hace un impacto importante en cualquier computadora personal. Y todo surge gracias a uno de los grandes genios y percusores de la computación moderna Von Neumann. Ésta fue utilizada en la Univac en 1945.

Figura 1. Arquitectura Von Neumann. Fuente: Wikipedia.

De acuerdo a esta arquitetectura se tiene la siguiente definición:

Máquina programada de propósito general capaz de realizar una serie de operaciones básicas siguiendo un
conjunto de instrucciones que le son proporcionadas a través de un programa encaminado a resolver un
problema.

Wintermute

En la figura 1. se puede observar las caracteristicas y elementos que tiene un ordenador hasta la actualidad, a continuación se procede a repasar algunos de sus elementos:

  • Memoria: Su misión consiste en servir de almacenamiento de la información dentro de la computadora, sean programas o datos, y sin hacer distinción entre código y datos (no hay una memoria para datos y otra para código ejecutable, está unificada).
  • Dispositivos de Entrada / Salida (E/S): Engloban a todos aquellos perífericos omo pueden ser ratones, monitores, teclados, entre otros, es decir, todo loque proporcione datos al PC o através d elo cual salgan de él.
  • Bus de comunicaciones: Las operaciones de acceso a datos, de manejo de periféricos y otras, han de realizarse a través de un BUS (hilos de comunicación); su misión engloba por ejemplo la transferencia de datos entre memoria y procesador.
  • CPU: Unidad Central de Proceso (Central Processing Unit): es la encargada de controlar y ejecutar todas las funciones del computador. Es la que determina en qué condición se ejecuta el ´odigo y como han de mandarse los datos, generando además todas las señales de control que afectan al resto de los partes.

Memoria

La memoria de un ordenador se organiza en varios niveles que se organizan en forma piramidal, en la cima aquello que es más rápido y también más escaso (registro) y en la base lo más lento pero al tiempo mas abundante (discos).

Los registros pertenecientes al microprocesador son los más rápidos (con un tiempo de acceso que suele estar entre 1 y 5 nanosegundos (ns) ) aunque por su coste el tamaño es reducido (normalmente no más de 256 bytes). La memoria caché, la más lenta, tarda entre 5 y 20 ns (tiempo de acceso) pero con un tamaño mayor que a pesar de todo pocas veces sobrepasa el megabyte.

La memoria principal, lo que se suele conocer como RAM, tiene un tamaño mayor – las configuraciones estándar de las computadoras personales, difícilmente bajan ya de los 1024 Mb – pero el tiempo un acceso es más lento (entre 60 y 200 nanosegundos). Finalmente, con la memoria secundaria hacemos referencia normalmente al disco duro, que es utilizado por el ordenador como memoria virtual. entre los distintos niveles de la jerarquía, debe haber una correspondencia de los datos.

Por ejemplo, cuando accedemos a una base de datos, esta se carga en memoria, se tendría que hacer una actualización desde la memoria al disco duro para que los cambios sean permanentes; así, siempre que modifiquemos algo en un nivel de la jerarquía, tarde o temprano habrá que transferir estos cambios a los niveles inferiores hasta llegar a la base de la pirámide.

Del mismo modo sucede en la relación entre memorias caché y principal; en la memoria caché se van a cargar partes de la memoria principal que se supone va a ser más utilizadas, que otras, cuando se produzca una modificación de lo que contiene la caché, habrá que actualizar de alguna manera la memoria principal. Se puede decir lo mismo de la relación entre caché y registros del micro, pero estos registros han de ser descritos más adelante en detalle pues su importancia va a ser capital para la programación en el lenguaje ensamblador. De cada procesador, esta en decidir cuales son las políticas de extracción (decidir que información se sube al nivel superior y cuando) y de reemplazo (decidir qué porción de la información de ese nivel superior ha de ser eliminada).

Figura 2. Pirámide de memorias según su velocidad y tamaño.

Memoria Virtual

En un sistema dotado de memoria virtual, dos niveles de la jerarquía de memoria (vea figura 2) son tratados hasta cierto punto como si fueran uno sólo; esto es, las memorias principal y secundaria (memoria RAM y disco duro generalmente) se acceden mediante lo que se denomina direcciones virtuales (no se olvide que en cualquier caso que un programa ha de residir en memoria principal para ejecutarse, al igual que los datos para ser accedidos o modificados).

Para llevar a cabo esta labor, al ejecutarse un programa se asignará un espacio virtual a este, espacio que no va a compartir con ningún otro programa y gracias al cual tampoco va a ver a ningún otro programa más que al propio sistema operativo. Es decir, suponga que se tiene tres programas ejecutándose, P1, P2 y P3, y que el sistema virtual maneja direcciones desde la 0x00000000 a la 0xFFFFFFFFh (en numeración hexadecimal). Cada uno de estos tres programas podrá ocupar la parte que quiera de esta memoria virtual, y aunque dos de ellos ocuparan la misma dirección virtual no se “colapsarían” dado que son procesador y sistema operativo quienes mediante la MMU (Memory Management Unit) deciden a qué parte física de la memoria principal (o a qué zona de la memoria secundaria) corresponde la dirección virtual (ojo, el espacio virtual 0x00000000 a 0xFFFFFFFFFh es independiente en cada uno de los programas). Es por ello, que excepto por mecanismos que se implementen a través del sistema operativo, el código y datos de un programa no podrá ser accedido desde otro.

En cualquier caso, un programa no puede acceder a todo el espacio virtual, sino a la parte que le reserva el
sistema operativo, ya que parte de él estará ocupado por código perteneciente al propio sistema operativo. Por último, destacar que este espacio virtual se divide en páginas virtuales, cada una normalmente de 4Kb de tamaño; sobre estas se mantendrá una tabla de páginas, una estructura que contiene la información acerca de donde residen las páginas de un programa en ejecución. Si se intenta acceder en lectura o escritura sobre una página que está en la memoria principal no habrá problemas y la MMU traducirá la dirección virtual a la posición física en memoria. Sin embargo, si se intenta acceder a una página que resida en el disco duro, se generará un fallo de página y se cargarán esos 4Kb que estaban en el disco duro sobre la memoria principal, pudiendo, ahora sí, leer o escribir sobre la información contenida en ella.

La aplicación práctica la se ha visto todos en sistemas como Linux o Windows; se reserva un espacio de tamaño variable como “memoria virtual” (el término es en realidad incorrecto tal y como se utiliza en Windows, ya que la memoria virtual abarca la RAM que tenemos y lo que asignemos para el disco duro), y esto va a permitir como gran ventaja cargar programas más grandes que la memoria que se tiene. Evidentemente, si se arranca diez programas que ocupan 20Mb cada uno en memoria y la memoria es tan sólo de 128Mb no se va a poder tenerlos a la vez en memoria, con lo cual el sistema de memoria virtual se hace necesario.


Lo mismo sucedería, si se intenta cargar un programa que necesita 140Mb de memoria. Así, aquellos programas que se estén utilizando residirán en la memoria virtual, y aquellos que no, en el disco duro. Cuando utilicemos los otros, las partes menos utilizadas de la memoria principal pasarán al disco duro, y se cargarán desde él las que se esté utilizando.

Continuando con la arquitectura de Von Neumann se procede a unos conceptualizar el resto de las partes:

Dispositivos de Entrada y Salida (E / S) | Input y Output I/O (por sus siglas en ingles)

Se tienen dispositivos de entrada como: ratón, teclado, scanner; es decir, son periféricos que permiten la lectura o entrada de datos al computador. Los de salida se tiene a los mas tradicionales como el monitor, o una impresora. Existe algunos tipos de dispositivos que cumplen ambas funciones, como los discos duros, disketeras, módems, entre otros.

Suelen llamarse “periféricos”, y en realidad cualquier cosa, desde un detector de movimiento a una cámara de video, pueden utilizarse como dispositivos de E/S. La tarea más compleja respecto a estos dispositivos, es su control mediante el microprocesador; por ejemplo un módem conectado al puerto serie de un PC ha de ponerse de acuerdo con el procesador respecto a la forma de intercambiar sus datos o la velocidad con la que lo hace. Se necesita que haya una coordinación entre ambos para que uno lea a la misma velocidad a la que el otro escribe, y para interpretar adecuadamente los datos transmitidos. Además, el procesador debe de mantener una jerarquía dando prioridad antes a unos periféricos que a otros (atender una petición del disco duro puede resultar más importante que atender una
del teclado).

Control de los dispositivos de entrada / salida

Existen tres modos básicos de realizar operaciones de E/S: programada, por interrupciones y por DMA (direct memory access) se listan a continuación:

  1. La programada: exige que el procesador esté pendiente de las operaciones realizadas por los periféricos; por ejemplo, en caso de controlar mediante este sistema un disco duro, la CPU tendría que ordenar la lectura de disco y estar pendiente mediante comprobaciones de si esta lectura ha sido realizada hasta que esto sea así; este es el método menos efectivo, puesto que mientras la CPU está haciendo estas revisiones para saber si la operación ha concluido no puede hacer otras cosas, lo cual reduce mucho su efectividad.
  2. Por interrupciones, el procesador se “olvida” una vez mandada en el ejemplo anterior, esa orden de lectura de disco, y sigue ejecutando las instrucciones del programa actual. Cuando esta operación haya terminado, y en general cuando un periférico tiene datos dispuestos para enviar o recibir, se generará lo que se conoce como “interrupción”; esto es, que la ejecución del programa por el procesador se detiene, y salta a una rutina de tratamiento de interrupción que hace lo que tenga que hacer con esos datos. Salta a la vista, que este sistema (utilizado con frecuencia) es mucho más efectivo que la programada, puesto que libera al procesador de estar pendiente de la finalización de las operaciones de E/S.
  3. DMA libera por completo al procesador no sólo de la tarea de control sobre estas operaciones como ya hacía el sistema por interrupciones, sino también del tener que preocuparse por la transferencia de los datos. Parte de la memoria virtual se “mapea” sobre el periférico; esto es, si por ejemplo tenemos una pantalla de 80×25 caracteres, en memoria se reservará una zona de 80×25 bytes tales que cada uno representará un carácter (que se halla en ese momento en la pantalla). Así pues, para escribir o leer lo que hay en pantalla en lugar de tener que estar el procesador enviando órdenes, se realizaría de forma transparente, de modo que leyendo de la memoria se leería diréctamente del monitor, y escribiendo en ella se modificaría lo que está escrito sobre él.

Buses de comunicación

Todas las operaciones mencionadas, han de realizarse a través de un BUS. Básicamente, se tiene tres tipos de buses, los cuales se listan al calce:

  • BUS de datos: Transfiere información, como su propio nombre indica. Por ejemplo, un bus de datos une el procesador con los discos duros o la memoria, para que estos puedan ser accedidos y su información transferida de un lugar a otro.
  • BUS de control: Transporta las señales que se utilizan para configuración y control; pueden ser por ejemplo señales que decidan qué periférico ha de transmitir en un determinado momento, indicaciones para la memoria RAM de si debe de leer o escribir.
  • BUS de direcciones: Su utilidad se hace patente en operaciones como accesos a memoria; transportaría la indicación acerca del lugar de donde hay que leer o escribir en la RAM, o en el acceso a un disco duro el lugar físico de este donde se quiere leer o escribir.


Estos buses se combinan constantemente para poder llevar a cabo satisfactoriamente las operaciones requeridas por el procesador central. En una lectura de memoria, la CPU mandaría señales para activar el proceso de lectura en la RAM, mientras que por el bus de direcciones viajaría aquella dirección de la que se quiere leer. Una vez llegados estos datos a la memoria, por el bus de datos viajaría hasta el procesador aquella información que se requirió en un principio.

CPU

Se trata del “gran cerebro” del computador, encargada del control de todo lo que sucede y de la ejecución del
código. Se compone de tres partes principales; la ALU (Arithmethic-Logic Unit), la Unidad de Control y la
Unidad de Registros.

ALU (Arithmethc Logic Unit)

Su misión es la de realizar operaciones aritméticas. Dependen del diseño, aunque se encontraran como básicas suma y resta; puede que se quiera disponer de otras más complejas como multiplicación y división. Además, existen operaciones lógicas:

  • AND: Un AND hecho a dos bits devuelve 1 sólo si los dos bits son 1 (por ejemplo, 011 AND 101 dará como resultado 001). Equivale al “Y” lógico (es decir, al resultado en lógica de algo como “se da X y se da Y”, frase que sólo sería verdadera en caso de darse X e Y).
  • OR: Un OR hecho a dos bits devuelve 1 si al menos uno de los dos bits implicado en la operación es 1 (un 011 OR 101 da como resultado 111). Equivale al “O” lógico (el resultado de algo como “se dan X, Y o ambos”, sentencia cierta en caso de darse X, Y o ambos).
  • XOR: Un XOR, (eXclusive OR, O exclusivo) da 1 operando sobre dos bits si uno de los dos bits es 1 y el otro 0 ( la operación 011 OR 101 resulta 010). Este “O exclusivo” en lógica es el que se daría en un “X está vivo o está muerto”; una de las dos condiciones ha de cumplirse para que esta sentencia sea cierta.
  • NOT: Esta operación trabaja con un sólo bit; lo que hace es invertirlo (así, NOT 011 dará 100 como resultado). Las operaciones con la ALU se pueden indicar mediante una señal de control con los bits suficientes como para diferenciar entre los tipos de operación existentes. Es decir, si se tiene 2 bits para la señal de control, las posibilidades de estos bits serán “00-01-10-11”, lo cual da como resultado una ALU que pueda hacer cuatro funciones distintas. Con 3 bits, tendríamos “000-001-010-011-100-101-110-111”.

Es decir, 8 operaciones posibles. Además de esta señal de control, se tiene dos entradas de datos; esto es, los operandos de la función que se va a realizar. Así, si queremos hacer un AND entre dos números, meteremos cada uno de ellos por una entrada de datos y seleccionaremos el AND. Por supuesto, habrá al menos una salida conectada para el resultado de la operación.

La unidad de control

Es la que realiza el secuenciamiento del programa que estoy ejecutando; esto es, la ejecución de la instrucción actual y la obtención de la siguiente. Su función es obtener las señales de temporización y control para ejecutar según los datos que entran, determinando el funcionamiento de la CPU y su comunicación interna.

Al ir a ejecutar una instrucción, la unidad de control pedirá que sea cargada y la analizará, viendo qué tiene que hacer en la CPU para que lo que la instrucción dice que ha de hacerse, llegue a buen término; por ejemplo, si esta instrucción es un AND de dos elementos, mandaría estos dos a la ALU y activaría las señales de control para que realizase un AND, para después transferir el resultado donde la propia instrucción indicase.

La unidad de registros

Par termnar se tiene la unidad de registro con una gran importancia, ya que la CPU usa estos registros para no tener que estar siempre accediendo a la memoria. Un registro no es más que un “pedazo” de memoria con una velocidad de acceso muy grande, normalmente de un tamaño que no supera los 64 bits (siempre una cifra tipo 16, 32, 64, 128…).

Sus usos, son diversos; mientras que por ejemplo cuando se ejecuta una instrucción esta se guarda en un
registro mientras dura su procesamiento, pueden usarse también para almacenar datos con los que operar o hacer transferencias con la memoria, entre otros. Hay dos tipos básicos de registros:

  • Registros de propósito general

Podemos darles cualquier uso. Son accesibles, visibles al programador, que puede utilizarlos. Sirven para volcado de datos, instrucciones… por ejemplo, en el MC68000 de Motorola, existen 16 registros de 32 bits de propósito general (A0-A7 y D0-D7, para almacenar direcciones y datos respectivamente). En otros como los 80×86 de Intel tenemos otra serie de registros de 32 bits con nombres como EAX, EBX, ECX, EDX.

  • Registros de propósito específico

Son registros que utilizan la unidad de control; el programador no puede utilizarlos, al menos diréctamente. Los principales (cuyo nombre cambia según cada implementación pero que por lo general se suelen encontrar en toda CPU) son:

  • IR: Su misión es contener la instrucción que se está ejecutando por la CPU; es el Registro de Instrucción (o Instruction Register). Mientras la instrucción se esté ejecutando, se contendrá ahí.
  • PC: Program Counter o Registro de Contador de Programa. Su misión es contener la dirección de la instrucción siguiente a la que estamos ejecutando. Por ello, permite ejecutar un programa de modo secuencial (línea a línea), tal y como ha sido programado.
  • SR: Es el Registro de Estado, o Status Register. Su misión es reflejar en cada momento en qué situación se encuentran algunos detalles de la CPU (por ejemplo, almacena resultados de comparaciones) de cara a tomar decisiones, así como otros parámetros que pueden necesitar ser consultados. En la mayoría de las implementaciones este registro es, al menos, accesible.
  • SP: Registro de Pila o Stack Pointer; la función de la “pila” será explicada ya más adelante, pero es necesario para poder hacer llamadas a funciones en programas y para muchas otras cosas.
  • MAR: Registro de Dirección de Memoria (Memory Address Register): Es el que finalmente comunica la CPU con el bus externo. Concluída la instrucción, el PC se vuelca en el MAR, y el bus de direcciones localizará la siguiente instrucción según el contenido de este registro.
  • MDR: Registro de Datos de Memoria (Data Address Register): Es el que pone en contacto la CPU y el bus de datos, que contiene la información para ser transferida por él o para recibirla.

Comparte esta entrada en tus redes sociales