¿Cómo funciona una computadora?

¿Cómo funciona
una computadora?
INTRODUCCiÓN
A
Lasdescripciones
un programa
forman
hora se estudiará con cierto detalle el modus operandi de una computadora digital electrónica, sin emplear ningún tipo de terminología
electrónica o de ingeniería. El hilo conductor será, sencillamente,
una idea descriptiva de los procesos que en términos conceptuales deben suceder dentro de la máquina para lograr lo que se desea.
De este modo, nos preocupará el concepto de necesidad lógica: lo que debe
suceder, y los pasos necesarios y su orden, para llegar a obtener un resultado
deseado. El desafío de este capítulo es llegar a inventar y "construir" la
computadora, * partiendo de la sencilla idea de que en ciencia y tecnología las
cosas son como son por alguna razón bien específica, y no por casualidad o
por capricho de algún genio inventor.
Como ejemplo inicial se propone pensar en los pasos necesarios para realizar con una calculadora común la operación de sumar 5 + 7.
Para esto será necesario definir con cuidado dos tipos de objetos: los datos
y las operaciones o funciones que actúan sobre éstos. En realidad la primera
etapa no es difícil; cualquiera que haya usado una calculadora de bolsillo
* En términos pedagógicos, el hecho de que las computadoras fueron en realidad inventadas
hacia 1947 no debe desanimarnos. Lo importante es tener la capacidad de descubrirlo por medios propios. En su libro El miedo a la libertad (escrito en 1941), Erich Fromm (1900-1980)
analiza los mecanismos psicológicos del acto creativo y descubrimiento de la verdad, y propone:
"Por original no quiero significar, como ya se ha señalado, que una idea no haya sido pensada
antes por algún otro, sino que se origina en el individuo, que es el resultado de su propia actividad y que en ese sentido representa su pensamiento." (Paidós, México, 1994, p. 233.)
42
Capítulo 2
¿Cómo funciona una computadora'?
sabe cómo hacerlo. El problema interesante consiste en indagar la forma de
describir los pasos efectuados y de comunicárselo a la computadora después.
y aquí aparece la necesidad de definir el concepto de programa, y es también aquí donde se gesta la concepción de las modernas computadoras
programables y de la teoría de la programación que permite el modelado de
la realidad.
Es claro que para lograr esta suma hay que informar a la calculadora qué
operaciones se desea hacer y sobre cuáles datos se van a aplicar. Normalmente se comunican los datos a la calculadora presionando las teclas que
describen la operación por efectuarse. El siguiente es el proceso con detalle:
1. Presionar la tecla 5 (con esto se avisa a la calculadora que debe guardar
este número en alguna memoria temporal, hasta decidir lo que se hará
con éste).
2. Presionar la tecla + (ahora la calculadora traslada el 5 a un acumulador
interno especial y está lista para recibir el segundo operando).
3. Presionar la tecla 7 (con lo que se efectúa la suma en el acumulador; la
calculadora mantiene el resultado internamente).
4. Presionar la tecla = (esto indica a la. máquina que ha terminado la serie
de operaciones y que debe liberar el resultado).
5. La máquina despliega el resultado: 12.
Si ahora se decidiera hacer la operación 5/7 habría que volver a iniciar el
proceso desde el paso 1, cambiando solamente la tecla + del paso 2 por la
tecla correspondiente a la división. Un somero análisis revela que en realidad la calculadora "no se ha dado cuenta" de las operaciones que hizo, porque
se realizaron como resultado de un proceso externo a la máquina misma; es
decir, todo ha dependido del orden de los pasos (acciones) que decidimos efectuar con ésta, simplemente usándola como medio. Allí no hubo comunicación; sólo se utilizó el mecanismo.
Para que la máquina "entienda" lo que se desea hacer (el proceso de la
suma, de la división o cualquier otro) y lo pueda realizar de manera interna,
debemos emplear las características únicas del lenguaje como medio de expresión, y escribir entonces un programa para que luego se ejecute.
¿Qué es un programa? La definición más elemental es que un programa es un conjunto explícito de pasos a seguir para lograr un fin determinado.
En este caso, lo que interesa es lograr la suma de dos números, para lo
cual hay que especificarle a la máquina las siguientes instrucciones:
1.
2.
3.
4.
Observar el primer número.
Llevarlo al acumulador para sumarlo con el número que sigue.
Efectuar la suma usando este segundo número que ahora se observa.
Mostrar el resultado.
Pero hay todavía varios problemas por resolver para estar satisfechos con
este programa. El primero de éstos consiste en que está escrito en español, y
2.2
FIGURA 6.
El modelo de von Neumann
43
Esquema básico de una computadora.
la máquina no entiende este lenguaje. * Otro problema es definir dónde se
almacenarán los números 'que se desea que la máquina "observe". Uno más
se refiere a dónde y cómo almacenar las instrucciones del programa.
Para responder a estas cuestiones se definirá lo que se conoce como el
modelo de von Neumann. Además, si logramos resolverlas, habremos convertido la calculadora en una verdadera computadora, porque la diferencia
entre ambas consiste precisamente en la capacidad de seguir instrucciones
escritas en un lenguaje.
2.2
EL MODELO DE VON NEUMANN
La idea central del modelo de computación propuesto por John von Neumann
es almacenar las instrucciones del programa de una computadora en su propia memoria, logrando con ello que la máquina siga los pasos definidos por
su programa almacenado.
En la figura 6 se observan las relaciones estructurales existentes entre
las diversas unidades que configuran la máquina. Este esquema se sigue
empleando en prácticamente todos los modelos de computadoras y presenta
la configuración general de una computadora de programa almacenado, que
es otra denominación para una máquina que funciona con el modelo de von
Neumann. Como se decía en el capítulo anterior, es muy parecida al diseño
original de Charles Babbage, aunque no está basada en ése.
La unidad central de procesamiento (UCP -de aquí en adelante se
le llamará así- aunque también es común referirse a ésta como CPU, por
sus siglas en inglés) contiene a la unidad aritmética y lógica (hace los cálculos) ya la unidad-de control (define su orden y secuencia).
Lafunción.de la UCP es clara: ejecutar instrucciones. Pero para ello necesariamente deben cumplirse estas condiciones:
* Ni cualquier otro. El único lenguaje que una máquina es capaz de seguir -aunque
lo pueden hacer- es el "lenguaje de máquina".
no todas
44
Capítulo 2
¿Cómo funciona una computadora?
•
•
Que las instrucciones sean entendibles por la UCP.
Que estén almacenadas en la memoria.
Para cumplir con la primera condición se vuelve imprescindible codificarlas
de alguna forma mediante números, para entonces construir circuitos electrónicos (Babbage intentó hacerlo con engranes) que se activen cuando reciban cada código numérico y efectúen la acción u operación codificada. Esto se
hará más adelante.
Para la segunda condición se abordará el problema del almacenamiento
de números definiéndolo precisamente como la función de la memoria.
Para nuestros propósitos, la memoria será un conjunto de celdas (o casillas electrónicas) con las siguientes características:
•
•
Cada celda puede contener un (y sólo uno) valor numérico.
Cada celda tiene la propiedad de ser "direccionable", es decir, se puede
distinguir una de otra por medio de un número unívoco llamado su dirección.
Esto implica que las celdas de la memoria deben estar organizadas de
modo que faciliten la localización de cualquiera de ellas con un esfuerzo mínimo. El modo más sencillo de hacer esto es organizándolas en un conjunto
numerado secuencialmente, para luego hacer referencia a las celdas por medio
de su dirección. Se usará un apuntador
para dirigirse a alguna celda, es
decir, para especificar su dirección.
Así, el conjunto de celdas de memoria se puede ver como se muestra en la
figura 7.
Cada celda tiene una dirección. Por ejemplo, la celda 2951 contiene un 23.
Debe quedar clara la existencia de dos conceptos independientes: una cosa es
la dirección de una celda y otra es su valor, aunque casualmente pudieran
coincidir.
Se dispone ya de una manera de almacenar (y recuperar) valores por medio
de una dirección unívoca, como se verá a continuación cuando se definan dos
operaciones elementales sobre la memoria: leer el contenido de una celda y
escribir un valor en una celda.
2950
2951
2952
!
Apuntador
FIGURA 7
Celdas de memoria
y direcciones.
2953
2954
2.2
El modelo de von Neumann
45
Si se supone a la memoria de una computadora como una especie de almacén que funciona en forma autónoma del procesador, los siguientes deberán ser los pasos necesarios para efectuar las dos operaciones primitivas.
Operaciones
memoria
sobre la
Para leer:
Especificar cuál celda se va a leer (esto es, proporcionar su dirección).
Esperar un tiempo fijo para que los circuitos de la memoria traigan el
valor depositado en esa celda (la celda no pierde ese valor; sólo se trae
una copia del dato y no el dato mismo).
e) Recoger el dato y dar por terminada la operación de lectura.
a)
b)
y para escribir:
a) Proporcionar a la memoria el dato que se desea depositar en una celda.
b) Especificar la dirección de la celda sobre la que se desea hacer la escritu-
ra del dato.
e) Esperar un tiempo fijo para que los circuitos de la memoria depositen el
dato en la celda designada y así terminar la operación de escritura. (Si la
celda en cuestión tenía ya un valor, éste se pierde, pues es reemplazado
por el nuevo.)
Necesidad de la
codificación
Ahora hay que enfrentar el problema que se expresó antes: cómo almacenar las instrucciones en la memoria; es decir, debemos encontrar una forma
de acomodar las instrucciones en las celdas. Esto lleva necesariamente al
concepto de codificación. En efecto, si en las celdas de memoria sólo caben
números, entonces habrá que convertir las instrucciones en números para
poder emplearlas.
Para codificarlas se debe considerar cuántas y cuáles habrá disponibles,
así como el esquema de codificación a emplear.
El primer factor depende fundamentalmente de la capacidad de la unidad de control del procesador central para hacer operaciones; cuanto más
compleja -y costosa- sea la unidad central de procesamiento, tanto mayor
será el número de instrucciones diferentes que podrá efectuar. De igual modo,
debe encontrarse un código adecuado para que a cada instrucción definida
corresponda un, y sólo uno, valor numérico. Para este propósito usaremos
una especie de "diccionario electrónico" (que forma parte de la unidad de
control: es lo que Babbage no pudo realizar con la tecnología de su tiempo)
que especificará, por ejemplo, los siguientes códigosnuméricos. (Además, para
nuestros fines pedagógicos escribimos a la izquierda una columna con el nombre de la instrucción, pero debe quedar claro que los circuitos de la máquina
sólo están diseñados para reconocer los códigos, no sus nombres.)
46
Capítulo
2
¿Cómo funciona
una computadora'?
De aquí en adelante se empleará el nombre lenguaje de máquina para
referirse al código manejado por la unidad central de procesamiento de la
computadora; los circuitos electrónicos de la unidad de control de la computadora "reconocen" Yejecutan precisamente las instrucciones codificadas en
ese lenguaje de máquina.
2.2.1
Un primer programa
Ahora es posible escribir un primer programa completo, usando el modelo
recién descrito. Se continuará con el problema de sumar 5 + 7.
Primera consideración: se requieren tres casillas, dos para los datos (5 y
7) Yuna para depositar el resultado. Se escogen las casillas 20, 21 Y22. (No
hay ninguna razón especial para haberlas escogido; para nuestros fines, tres
casillas cualesquiera son adecuadas.)
Segunda consideración: hay que definir con detalle las operaciones por
efectuar y su orden, así como obtener una codificación adecuada (o sea, escribirlas en lenguaje de máquina).
Tercera consideración: hay que introducir todos los datos (e instrucciones) en la memoria.
Trabajando con nuestro programa de la página 42, se detecta la necesidad de inventar varias operaciones de la máquina. Se requiere, por lo pronto,
una instrucción para llevar el contenido de una celda al acumulador (que
es una celda especial, o registro, contenido en la UCP), otra para hacer la
suma y una más para devolver el contenido del acumulador a una celda de
la memoria.
La forma de la instrucción para llevar el contenido de una celda al acumulador es
CARGA <dirección>
donde CARGA es el nombre que dimos a la instrucción, y la <dirección> indica la celda de memoria cuyo valor se desea llevar al acumulador. Cabe aclarar que CARGA es el nombre simbólico (o mnemónico) de la instrucción,
empleado para que éstas sean legibles por nosotros, pero primero fue necesario asignarle un código numérico interno. Sin importar ahora cuál sea éste,
ocupará el contenido de una celda de la memoria. De la misma manera, la
dirección será un número que ocupará un lugar en otra celda. Esto significa
que la instrucción CARGA ocupará dos celdas en la memoria: una para el
código de la operación y la otra para la dirección a la que hace referencia. Es
decir, su longitud es dos.
En términos generales, habrá instrucciones que ocupen una, dos y hasta
tres o más celdas de memoria. (¿Podrá haber instrucciones de longitud cero?
¿Por qué?)
Las demás instrucciones que se requerirán son:
2.2
GUARDA <dirección>
SUMA <dirección>
Deposita
memoria
Suma al
memoria
El modelo de von Neumann
47
el valor del acumulador en una celda de la
(ésta es la inversa de la anterior), y
acumulador el contenido de la celda de
descrita por la dirección.
Así que las instrucciones de nuestra máquina serán por lo pronto las siguientes:
Nombre
de la instrucción·
Código interno
Longitud
de la instrucción
(Los códigos internos para el lenguaje de máquina que se escogieron son
arbitrarios, sin embargo, se debe tener cuidado de usarlos consistentemente.)
Se escribirá el programa en forma tabular. En la parte izquierda del renglón se colocará el nombre simbólico de la instrucción, seguido de la dirección
a la que haga referencia (si se da el caso); luego se describe brevemente el
renglón (si se considera necesario) y, por último, se escribe su equivalente en
el código interno que "entiende" el diccionario electrónico de la computadora.
Para continuar, se supone que la celda 20 contiene un 5 y la celda 21 un 7,
sin preocuparse por ahora de cómo se colocaron allí esos números.
He aquí el programa para sumar 5 + 7.
De este simplísimo programa se puede aprender varias cosas. Fue necesario inventar una nueva instrucción (ALTO) para lograr que la secuencia
-cuando se ejecute- llegue a un fin. Obsérvese que esta nueva instrucción
ocupa una sola casilla de memoria, pues no es necesario que haga referencia
a alguna dirección.
Otra cuestión importante es la aparición de dos programas: uno escrito
en lenguaje simbólico y mnemónico (más fácil de reconocer para nosotros ya
que es cercano a nuestro lenguaje), y otro -a la derecha- que está descrito
en código numérico (el único que reconoce la computadora).
Se llamará programa fuente al primero y programa objeto al segundo. Esto es, el programa fuente es aquel que está escrito en un lenguaje similar al nuestro (pero inaccesible para la computadora), mientras que el
programa objeto ya está traducido al código que la máquina reconoce. En
este caso fue la misma persona quien escribió ambos programas; por lo gene-
48
Capítulo
2
¿Cómo funciona
una computadora?
ral será tarea del programador escribir el programa fuente, y la propia computadora lo traducirá a lenguaje objeto.
El programa objeto, entonces, es:
20203021022270
que, obviamente, es por completo ininteligible para un ser humano.
Otro aspecto fundamental es entender que este programa sirve para sumar cualquier par de números, siempre y cuando residan en las casillas 20 y
21. Esto es realmente importante, pues significa, ni más ni menos, que es
una especie de "programa universal" para sumar dos números, sin importar
cuáles sean. Claro que esto no resulta impresionante por ahora, pero si se
piensa en un programa universal para calcular tablas de amortizaciones bancarias, u otro para invertir matrices de orden 90 x 90, se apreciarán las ventajas de esta nueva herramienta.
Resta tan sólo introducir el programa objeto en la memoria de la computadora para que pueda ejecutarse luego. Aquí es crucial elegir las casillas de
la memoria que se utilizarán para almacenar el programa; esto es, en qué
sección de la memoria se va a cargar el programa.
Se decidió hacerlo a partir de la celda 10. (se puede cargar a partir de
cualquiera que se encuentre desocupada, siempre que se esté seguro de la
existencia de suficientes celdas secuenciales vacías).
Una vez cargado, el programa objeto se verá como se muestra en la figura 8.
Cada celda contiene un solo número. La celda 22 contiene un número no
especificado todavía -el resultado de la suma-, que se obtendrá una vez
ejecutado el programa.
Cada una de las dos primeras celdas contiene un número 20, pero en la
primera éste representa el código de la instrucción CARGA, mientras que el
mismo 20 representa, en la segunda celda, la dirección 20. Obsérvese cómo
una celda puede contener un mismo número que significará dos cosas diferentes, dependiendo del orden en que aparezcan con respecto al inicio.
Cuando se ha cargado el programa objeto a partir de la celda 10 de la
memoria, debe encontrarse un procedimiento para lograr que la computadora comience a ejecutarlo y poder así obtener los resultados deseados.
Aquí se hará un paréntesis para describir con cierto detalle cómo funciona la unidad de control del procesador central de la computadora.
2.2.2
La unidad de control
La función principal de la unidad de control de la UCP es dirigir la secuencia
de pasos de modo que la computadora lleve a cabo un ciclo completo de ejecu-
~~"llttLjr~??,
l·
10
FIGURA 8
11
12
13
14
lS
16
Programa objeto cargado en memoria.
20
21
22
2.2
El modelo de von Neumann
49
11
IV
FIGURA 9
III
Modelo digital de la unidad de control.
ción de una instrucción, y hacer esto con todas las instrucciones de que conste el programa. Los pasos para ejecutar una instrucción cualquiera son los
siguientes:
El ciclo de ejecución
de la UCP
l. Ir a la memoria y extraer el código de la subsecuente instrucción (que
estará en la siguiente celda de memoria por leer). Esto se logra mediante
un registro apuntador (que forma parte de los circuitos electrónicos de la
unidad de control) que recibe el nombre de contador de programa
(CP). Este paso se llama ciclo de fetch en la literatura computacional
(to fetch significa traer, ir por).
11. Decodificar la instrucción recién leída (determinar de cuál se trata).
111.Ejecutar la instrucción.
Iv. Prepararse para leer la siguiente casilla de memoria (es decir, actualizar
el CP para que apunte a la celda que contiene la siguiente instrucción), y
volver al paso I para continuar.
La unidad de control ejecutará este ciclo de cuatro "instrucciones alambradas" a una velocidad enorme. * Se les llama así porque no residen en memoria, ni fueron escritas por ningún programador, sino que la máquina las
ejecuta directamente por medios electrónicos, y lo hará mientras esté funcionando (mientras esté encendida). La ejecución de estos cuatro pasos (que
forman un ciclo repetitivo) en una computadora es a razón de millones de
veces por segundo.
La unidad de control es una realización electrónica del modelo digital que
se muestra en la figura 9.
" Como se mencionó en el capítulo anterior, ésta es la diferencia principal entre hardware y
software. El primer término denota todo lo referente a los circuitos electrónicos de una computadora, mientras que el segundo hace referencia a los programas, que no son parte física de la
máquina, sino que residen en la memoria.
50
Capítulo
2
¿Cómo funciona
una computadora?
Se ha definido ya el modelo de von Neumann, Ahora se pondrá a funcionar sobre nuestro pequeño programa de ejemplo (que suponemos ya cargado
en la memoria).
2.2.3
Pasos en la ejecución de un programa
Se describirán todos los pasos con detalle por única vez para que el lector
pueda estudiarlos con detenimiento hasta estar seguro de haberlos comprendido. Le pedimos no seguir con la lectura si no cumple con esto.
o.
En virtud de que el programa comienza a partir de la celda número 10,
se debe indicar a la unidad de control que esa celda contiene la primera
instrucción. Para ello hay que colocar el número 10 en el registro contador de programa (es decir, apuntar a esa celda). Esto se representará por
CP <--- 10.
(Obsérvese que este paso es externo, esto es, no forma parte del programa, sino que se tiene que hacer "desde afuera" para iniciar la operación de la computadora.)
1. La unidad de control ejecutará el paso I e irá a la casilla 10 para leer su
contenido, que es 20.
2. La unidad de control ejecuta el paso II, con lo que decodifica el 20 recién
leído y determina que se trata de una operación CARGA. En este momento sucede algo de primordial importancia: como la instrucción 20
tiene una longitud de dos celdas, una para el código (20) y otra (la siguiente) para la dirección de la celda cuyo valor se cargará en el acumulador (que en este caso -de casualidad- también es 20), la máquina
deberá ajustar el valor del contador de programa para que apunte a esa
celda siguiente (i. e., la número 11 ).
3. La unidad de control ejecuta el paso III, con lo que efectivamente efectuará la operación de carga. Para esto, la computadora debe ir a la celda
11 y extraer su contenido, pero ahora ya no lo considerará como instrucción, sino como dirección, por lo cual irá a la celda 20 para extraer el
valor que contenga (que es 5).
En este momento hay que tener cuidado para que no haya confusión: el primer 20 (el de la celda 10) es la instrucción CARGA; el segundo 20 (el de la celda 11) es la dirección de la celda de memoria cuyo valor
se desea cargar en el acumulador. Esta instrucción completa, 2020, puede leerse de la siguiente manera: "cargar el acumulador con el valor que
esté contenido en la celda cuya dirección aparece a la derecha de donde
se está leyendo ahora". Aunque parece innecesariamente elaborado, es
imprescindible tener muy claro esto porque aquí reside la potencia del
modelo de von Neumann.
4. La unidad de control ejecuta el paso IV, para luego reiniciar todo el ciclo.
Obsérvese que se trata de una repetición ilimitada, que sólo terminará
cuando se ejecute la instrucción ALTO. Por lo pronto, el contador de programa se hace igual a 12; esto es, apunta a la celda número 12. Interna-
2.2
El modelo de von Neumann
51
mente los circuitos de la unidad de control le añadieron la longitud de la
instrucción recién ejecutada, que midió 2.
5. Se ejecuta, por segunda vez, el paso I de la unidad de control. Como CP =
12, se leerá esa celda, que contiene un 30.
6. Se decodifica esa instrucción, que es SUMA, por lo que el CP se prepara
para apuntar a la siguiente celda. (Recuérdese que la instrucción SUMA
ocupa dos celdas: una para el código de operación y otra para la dirección
de la celda cuyo contenido se sumará al acumulador.)
7. Se ejecuta la instrucción 30, con lo que se añade al acumulador el contenido de la celda 21 (la dirección 21 reside en la celda 13, que está inmediatamente a la derecha de la que se está ejecutando). Ahora el
acumulador contendrá un 12, es decir, 5 + 7.
8. El CP se actualiza para apuntar a la celda 14, en la cual (y no es casualidad, sino resultado del modelo) reside el código de la siguiente instrucción. Nuevamente en forma interna (paso IV) los circuitos de la unidad
de control suman al contador de programa la longitud de la instrucción
recién ejecutada.
9. Se lee la celda 14 y se extrae su contenido: 02.
10. Se decodifica la instrucción (GUARDA),por lo que se examina la siguiente
celda, que contiene la dirección de la celda en donde se guardará el contenido del acumulador.
11. Al ejecutarse esta instrucción se deposita el valor del acumulador (12) en
la celda número 22, o sea, se deja el resultado de la suma en la celda que
previamente se había separado para tal fin.
12. La unidad de control regresa al paso I, no sin antes actualizar el contador de programa con la longitud de la instrucción recién ejecutada, y
ahora apunta a la celda 16, que es donde reside la siguiente instrucción.
13. Se lee la celda 16 y se extrae su contenido: 70.
14. Se decodifica esta instrucción, que es ALTO. No se examina el dato de la
siguiente celda porque la instrucción 70 tiene una longitud de uno.
15. Se ejecuta esta instrucción, lo que detiene a la unidad de control y a la
máquina. De esta manera se rompe el ciclo de los cuatro pasos.
El compromiso fue que el lector seguiría estos dieciséis pasos con cuidado
(con ayuda del diagrama de la página 48), por lo cual habrá aprendido varias
cosas sobre el lenguaje básico de las computadoras, entre las que sobresalen
las siguientes:
•
Dado el contenido de una celda, la computadora no puede distinguir si se
trata de una instrucción o de un dato o una dirección.
• Debido a lo anterior, es responsabilidad de quien maneja la máquina indicar cuál es la celda en donde comienza el programa (esto se hizo por
medio del paso O, que se describió como externo al programa). En algún
capítulo posterior del libro se verá cómo la propia computadora, por medio del sistema operativo, será la que se encargue de esta tarea.
• Una vez que el contador de programa apunta a la celda que contiene la
primera instrucción, el resto del proceso ocurre de manera automática e
52
Capítulo
2
¿Cómo funciona
una computadora?
invisible para el usuario. Esto se debe a los ajustes internos que se hacen
al CP (en cada paso IV) que, a su vez, dependen de la longitud de la instrucción que se acaba de ejecutar.
2.3
EL LENGUAJE DE LA MÁQUINA
Este apartado es relativamente largo y analiza con más detalle el comportamiento del modelo de von Neumann. Su lectura puede omitirse en primera instancia si
sólo se está interesado en las consideraciones de tipo amplio o general.
También es importante anotar que todo lo que aquí se propone funciona precisamente de esa forma en las computadoras reales, aunque nosotros dejamos de
preocuparnos en un momento dado por cómo realizar los detalles.
Por lo pronto, nuestra "máquina de papel" reconoce algunas pocas instrucciones, pues los circuitos electrónicos de su unidad de control así lo especifican, y sería deseable incrementar la cantidad y tipo de éstas para disponer
de más poder de cómputo.
En principio, la tarea es sencilla: basta con idear alguna instrucción y
asignarle un código interno. Pero debe quedar claro que, en la vida real, cada
nueva instrucción implica necesariamente la incorporación de nuevos circuitos especializados (y miles de nuevos microtransistores), por lo que existe un
límite en la cantidad y complejidad de las instrucciones que un procesador
puede realizar, como se analizará con más detalle en el capítulo 3.
Evaluación de una fórmula
Escribiremos a continuación un programa para sumar tres números cualesquiera y restar otro número al total anterior. Es decir, se evaluará la fórmula
R = A + B + e - D (concediendo que tal cosa le pueda ser de utilidad a alguien). Supondremos que los cuatro números ya existen en memoria, en las
celdas 770 a 773, y que el resultado va a quedar en la celda 774:
CARGA
SUMA
SUMA
RESTA
GUARDA
ALTO
770
771
772
773
774
La codificación de este programa fuente en lenguaje de nuestra máquina
da como resultado el siguiente programa objeto equivalente:
20 770 30 771 30 772 33 773 02 774 70
Si se deseara posteriormente cargarlo a la memoria para ejecutarlo, habrá que seleccionar once celdas vacías secuenciales, que no incluyan de la
770 a la 774, porque ésas están reservadas para los datos.
,.
2.3
El lenguaje de la máquina
S3
Programa para obtener un promedio
Modos de
direccionamiento
Haremos ahora un programa para obtener el promedio de cuatro números
previamente almacenados en la memoria. Se considerarán únicamente operaciones sobre números.,enteros, por lo que el promedio será también un número
entero. Para obtener un promedio hay que hacer una suma y luego una división. Pero nuestra máquina aún no puede dividir, por lo cual prestamente inventamos, y comenzaremos a analizar, la instrucción para lograrlo, que tomará
el número que en ese momento esté en el acumulador y lo dividirá entre otro.
En general, las instrucciones aritméticas que el procesador puede realizar se efectúan sin punto decimal; es decir sólo con enteros. Los circuitos
para manejo de operaciones con punto flotante son tan complicados que no
todos los procesadores los incluyen; en capítulos posteriores se habla más
sobre esto.
Pero, ¿entre cuál número se hará la división de lo que contenga el acumulador? Existen dos posibilidades: entre el que resida en una celda de memoria cuya dirección se especifique, o bien entre un valor que a continuación se
indique.
Puede haber dos tipos de instrucciones de división, dependiendo del modo
en que hagan el acceso a su operando.
Una tiene la siguiente especificación:
DIV <dirección>
Divide lo que contenga el acumulador entre el contenido
de la celda de memoria descrita por la dirección.
y la otra efectuará la división ya no entre el número contenido en la celda
cuya dirección se especifica, sino simplemente entre el número que se indique de inmediato a continuación:
DIV-i <dato>
Divide lo que contenga el acumulador entre el número que
viene a continuación.
El nombre simbólico de la segunda variante contiene una letra i, porque
se trata de una división en modo inmediato. Ambas instrucciones tienen longitud 2: una celda para el código y la otra para la dirección del dato (en el
primer caso), o para el dato mismo (en el segundo).
Algunas instrucciones tienen variantes de direccionamiento en modo normal o en modo inmediato (u otros que luego se verán), dependiendo, como se
acaba de ver en el ejemplo, si el dato con el que operan está contenido en una
celda de memoria cuya dirección se indica, o bien si se encuentra inmediatamente después. Podría decirse que una operación en modo inmediato es menos general que la misma en modo normal, como se verá a continuación.
Por ejemplo, las instrucciones
CARGA
SUMA
GUARDA
7428
7429
7430
S4
Capitulo 2
¡Cómo funciona una computadora?
suman al número contenido en la celda 7428 el número que está en la 7429 Y
dejan el resultado en la 7430. Es decir, realizan la operación R = A + B,
llamando A, B YR a los contenidos de esas tres celdas, independientemente
de cuáles sean sus valores.
Pero la variante
CARGA-i
SUMA-i
GUARDA
Nuevas instrucciones
18
200
7430
únicamente hace la operaciónR = 18 + 200, con lo que siempre dejará el valor
218 en la celda que llamamos R (la 7430).
En general, las instrucciones en modo inmediato son menos interesantes
que las normales, porque están "comprometidas" con los valores que también
forman parte del programa, mientras que las otras trabajan sobre las direcciones de los valores, por lo que estos últimos no forman parte del programa,
sino que pueden ser datos independientes.
Podemos entonces suponer que el diccionario electrónico de nuestra máquina ha crecido (y también, por supuesto, la complejidad de sus circuitos).
Ahora se observa con nuevas instrucciones ya codificadas del siguiente modo:
Obsérvese que se añadió un CARGA en modo inmediato, para poder decir, por ejemplo,
CARGA-i
GUARDA
<valor>
<dirección>
y dejar un cierto valor preespecificado en alguna celda de memoria, para
cubrir alguna necesidad posterior.
2.3
El lenguaje de la máquina
55
También se añadieron dos instrucciones de longitud 1, INCR y DECR,
una que incrementa y la otra que decrementa en uno el contenido del acumulador, sin tener que hacer referencia a celdas de la memoria.
Si se quiere aumentar en uno el contenido de la celda 2951, por ejemplo,
resulta un poco más barato decir
CARGA
INCR
GUARDA
2951
2951
cuyo código es 20 2951 32 02 2951 (5 celdas), que efectuar las operaciones
CARGA
SUMA-i
GUARDA
2951
1
2951
porque el código de esto último ocupa 6 celdas:
20295131 01 02 2951
Las instrucciones INCR y DECR son útiles (y baratas) para el muy usual
caso de incrementar o decrementar la unidad.
Un programa
más elaborado:
búsqueda del máximo
Analizaremos ahora una situación más compleja: leer tres valores y seleccionar el máximo entre éstos. Aunque el planteamiento del problema es sencillb, para resolverlo nos veremos obligados a inventar más instrucciones y
a aprender más conceptos para seguir enriqueciendo las capacidades de
cómputo de la máquina.
La siguiente receta es una descripción de cómo resolver el problema:
Leer los tres números.
Considerar al primero como el mayor.
Comparar el mayor (o sea, el primero) contra el segundo: si el segundo es
mayor, entonces se le considerará como el mayor. (Y si no, no hay cambios.)
Comparar el mayor (haya sido el primero o el segundo) contra el tercero:
si el tercero es mayor, entonces se considerará a éste como el mayor. (Y si
no, no hay cambios.)
Mostrar el mayor.
Alto.
Si se hacen pruebas de ejecución de esta receta se verá que en efecto
selecciona al mayor de tres números, independientemente de los valores con
los que se trabaje, porque esta descripción es correcta desde un punto de
vista lógico:se presupone que el primero es el mayor y luego secuencialmente
56
Capítulo 2
Instrucciones
salida
,Cómo funciona una computadora?
de entrada/
se va comparando contra cada uno de los restantes. Si en cualquier momento
alguno de los nuevos números resulta mayor, sólo se abandona al antiguo
mayor y se escoge al nuevo, y así hasta terminar. Al final del procedimiento
el que haya sido el último mayor es efectivamente el máximo de todos.
La computadora no puede todavía "entender" este programa fuente porque aún no está escrito en lenguaje de máquina, por lo cual nuestra tarea
consiste en traducirlo y obtener un programa objeto equivalente. Lo primero
que se antoja es revisar la documentación técnica del diccionario electrónico
del procesador para simplemente escoger los códigos numéricos de las instrucciones requeridas. Pero sucede que nuestra máquina sólo dispone de las
instrucciones hasta ahora especificadas, y en ningún lado aparece alguna instrucción para leer un número, ni para mostrarlo, ni para comparar, por
lo que nos veremos obligados a seguir creando nuevas (y complicar el diseño
del hardware encargado de ejecutarlas).
Revisando el modelo de von Neumann (figura 6, de la página 43) se concluye que leer un número implica que el procesador central tome un valor del
mundo exterior por medio de la unidad de entrada (usando un registro especialllamado puerto de entrada). Ese valor individual llega de afuera y es
depositado en el acumulador como resultado de una instrucción de lectura,
que llamaremos IN, a la que asignamos el código 10. Como esta instrucción
no actúa sobre la memoria (sólo recoge un valor de la unidad de entrada y lo
deja en el acumulador) su longitud será 1.
IN
Toma el valor individual que esté en el puerto de entrada y lo deposita
en el acumulador.
En la misma forma se diseña la instrucción contraria, para tomar un número del acumulador y dejarlo (una copia, en realidad) en la unidad de salida: OUT, con código 11 y longitud 1.
Por fortuna en este libro no estamos preocupados por realizar todos los
detalles de las operaciones que se están definiendo, y por ello dejaremos alegremente de lado las consideraciones requeridas para leer o escribir datos de
tamaños diferentes. Es decir, simplemente supondremos que nuestras instrucciones IN y OUT son capaces de manejar datos individuales de longitud
"razonable".
Ya está resuelta una parte del problema, porque para leer un número y
llevarlo a la memoria bastará con ejecutar la secuencia de instrucciones
IN
GUARDA
Instrucciones
comparación
de
<celda>
donde <celda> especifica alguna dirección predefinida. Cada instrucción IN
mete un solo número al puerto de entrada, por lo que si se desea leer 27
valores diferentes, por ejemplo, el mismo número de veces habrá que desocupar el puerto de entrada copiando su contenido a una celda de memoria diferente cada vez.
Ahora se abordará el asunto de las comparaciones entre valores, y para
ello pensamos en una instrucción que determine si el valor A es mayor, me-
2.3
El lenguaje de la máquina
57
nor O igual al valor B. Como A y B son direcciones de celdas, entonces la
instrucción podría ser
COMP
100
200
que compararía el valor contenido en la celda 100 con el contenido en la celda
200. Sólo que entonces esta instrucción mediría tres celdas de longitud (una
para su código y dos más para las direcciones), lo cual resulta ser demasiado
caro. Para reducir el costo de ejecución de la instrucción (o sea, su longitud)
se efectuará la comparación entre el acumulador y el contenido de una sola
celda, y antes deberá cargarse el acumulador con el primero de los datos
para luego compararlos:
CARGA
COMP
100
200
La variante con modo de direccionamiento inmediato será
COMP-i
8
para compararar el contenido del acumulador contra, por ejemplo, el valor 8.
El procesador debe registrar de alguna forma el resultado de la comparación para permitir una posterior decisión si ésta fue como se esperaba, o bien al
revés de lo que se esperaba. Lo que importa es tener la posibilidad de actuar de
una o de otra forma, pero siempre bajo control del programa. ¿Qué significa
actuar de una forma? En el contexto de un programa quiere decir ejecutar una
cierta secuencia de instrucciones, por lo que actuar de otra forma simplemente
indicará ejecutar otra secuencia (diferente) de instrucciones.
Así, dentro del procesador debe existir un registro especial, que llamaremos bandera, para indicar el resultado de la última comparación entre dos
valores. Los circuitos de la unidad de control de manera automática harán
que la bandera asuma la o las posiciones resultantes de la comparación más
reciente que se hubiera ejecutado. Las diversas posibilidades son
IGUAL
=
DIFERENTE
<>
MAYORQUE
>
MENORQUE
<
MAYOR O IGUAL QUE
MENOR O IGUAL QUE
>=
<=
(No todas son mutuamente excluyentes: a la vez es cierto, por ejemplo,
que 8 es mayor que 4; que 8 es mayor o igual que 4, y que 8 es diferente de 4.)
De esta forma, la instrucción de comparación es entonces:
COMP <dirección>
Efectúa una comparación entre el contenido del acumulador y el de la celda cuya dirección se indica. Deja
el resultado de la comparación en la bandera.
58
Capítulo 2
¿Cómo funciona una computadora?
Como el modelo de von Neumann especifica que la ejecución es secuencial
(es decir, el contador de programa se incrementa para apuntar a la siguiente
instrucción del programa objeto), entonces ejecutar una secuencia B en lugar
de una A necesariamente implicará saltarse la primera de éstas; es decir, no
ejecutarla. Para ello se requiere de una instrucción del siguiente tipo:
BR> <dirección>
Brinca directamente a la celda con la dirección especificada si es que la bandera indica MAYOR QUE.
(Como la bandera puede estar en alguna(s) de las seis posibilidades ya
mencionadas -más de una a la vez porque no todas son mutuamente
excluyentes, como se dijo-, entonces habrá seis instrucciones de salto condicional diferentes: una para cada caso: BR=, BR<>, BR>, BR<, BR>=, BR<= ).
Supongamos, por ejemplo, que la secuencia A abarca de la celda 1250 a la
1300, y la secuencia B va de la 1301 a la 1400. La decisión de si se ejecuta
una u otra dependerá de una comparación anterior, por lo que en la celda
1248 habrá que colocar una de las instrucciones de bifurcación (o salto) condicional. El siguiente fragmento de programa no ejecuta la secuencia A si en
la celda 650 hay un 10:
Dirección
Instrucción
1244
1246
1248
1250
CARGA 650
COMP-i 10
BR = 1301
Primera instrucción de la secuencia A
1300
1301
Última instrucción de la secuencia A
Primera instrucción de la secuencia B
1400
Última instrucción de la secuencia B
Pero si en la celda 650 hay cualquier valor que no sea igual a 10, entonces
la instrucción BR= 1301 no tendrá ningún efecto, y el salto no se efectuará,
por lo que la ejecución continúa en la forma secuencial normal y se procede a
la ejecución de la secuencia A ...para continuar inmediatamente con las instrucciones de la secuencia B, que tal vez no era lo que se deseaba.
2.3
El lenguaje de la máquina
59
En efecto, resulta muy frecuente utilizar el resultado de una 'Comparación para escoger uno solo de dos caminos posibles: la secuencia' A o bien
la secuencia B, pero no ambas. Si así fuera, entonces al final de la primera secuencia habría que insertar una instrucción para alterar el flujo normal y saltar directamente hacia el final de la segunda secuencia, sin ejecutarla.
Esa nueva instrucción, de salto incondicional, tiene la siguiente forma:
BR <dirección>
Brinca inmediatamente a la celda con la dirección especificada.
Como las seis instrucciones de salto condicional, esta nueva también tiene una longitud 2.
A continuación se muestra el fragmento del programa anterior, ya modificado para obtener el efecto deseado de únicamente efectuar la secuencia de instrucciones A cuando la celda 650 no contenga un 10, y sólo ejecutar la secuencia B cuando ese valor sí sea 10 (o un caso o el otro, pero no
ambos):
1244
1246
1248
1250
CARGA
650
COMP-i
10
BR=1303
Primera instrucción de la secuencia A
1300
1301
1303
Última instrucción de la secuencia A
BR1401
Primera instrucción de la secuencia B
1400
Última instrucción de la secuencia B
A continuación se muestra el conjunto actual de instrucciones de lenguaje de máquina que conforman el "diccionario electrónico" de la unidad de
control de nuestra computadora. Aparecen en orden alfabético, aunque una
vez más repetimos que los circuitos electrónicos sólo manejan los códigos
numéricos; los nombres simbólicos no forman parte del diccionario y únicamente se emplean aquí por claridad en la exposición.
60
Caprtulo 2
¿Cómo funciona una computadora?
Con todos los nuevos elementos desarrollados ya no resulta tan difícil codificar el programa para encontrar el máximo entre tres números diseñado en la página 55, aunque no por ello carece de cierta complejidad.
Cuando se trabaja con computadoras (y más aún tratándose de lenguaje de
máquina), la atención a los detalles y minucias es enojosamente imprescindible.
Se hará uso de cuatro celdas de memoria para los datos: una para cada
uno de los tres números y otra para el valor mayor variable. Como la memoria consta de celdas numeradas secuencialmente, es forzoso definir desde
ahora las direcciones para los datos y el código del programa objeto. Sin ningún motivo especial decidimos utilizar celdas a partir de la 3000.
A continuación se muestran los programas fuente y objeto, escritos en
renglones que incluyen información extra para auxiliar en la comprensión.
Aparece subrayada la dirección de la primera instrucción ejecutable. Debe
quedar claro que el código objeto es únicamente la última columna.
2.4
Sistemabinario
61
Si el lector verdaderamente desea comprender cómo funcionan las computadoras (dejando a un lado marcas y modelos), entonces no podrá estar satisfecho sino hasta haber "ejecutado" el programa anterior: le recomendamos
tener cuidado y, para simular la ejecución, apuntar en una hoja los sucesivos
contenidos del contador de programa, el acumulador, la bandera y las celdas
de la memoria que contienen los datos. Pruebe los tres diferentes casos que
puede haber: cuando el mayor es el primero, el segundo o el tercero de los
números leídos. Por supuesto, el programa funciona para todos los casos y
posibilidades, independientemente de los valores escogidos. Si no fuera así,
no sería un "programa universal para determinar el mayor entre tres números cualesquiera" y tendría el poco interés que suele darse a los asuntos totalmente particulares y específicos, que sólo conciernen a sus dueños porque
no son generales ni se refieren a situaciones amplias o abiertas.
El alcance de este primer libro únicamente llega hasta estas ideas preliminares de la programación en lenguaje de máquina, por lo que con este
ejemplo concluye por ahora el tema y se pasará a analizar otros conceptos.
En un siguiente curso deben aprenderse las técnicas de programación en
otro tipo de lenguajes con mayor capacidad expresiva.
2.4
SISTEMA BINARIO
En una computadora real las celdas de la memoria no contienen números de
la forma descrita aquí (lo cual se hizo por comodidad), sino que se almacenan
en una forma más sencilla.
62
capítulo 2
¿Cómo funciona una computadora?
Qué implica almacenar
un número
Formas de representación
de números
Se ha visto que la unidad de memoria es el aparato cuya función es guardar (y recuperar) valores numéricos. Aunque la descripción física de la memoria no se dará sino hasta el siguiente capítulo, aquí debemos detenernos a
examinar las implicaciones inherentes al hecho de almacenar un número.
En efecto, almacenar un valor significa seleccionar (y mantener) uno de entre varios estados de un conjunto, en donde cada uno de esos estados tiene
como función representar precisamente ese número.
Desde esta perspectiva, un dado puede fungir como una unidad de memoria capaz de "recordar" un valor entre 1 y 6: basta con colocar alguna de sus
seis caras hacia arriba, por ejemplo, y mantenerlo así. * Pero si se requiriera
almacenar un número entre 1 y 400 habría entonces que construir un "hiperdado" con 400 caras. Es claro que mientras mayor sea la gama de posibles
valores a almacenar, más compleja será la unidad de memoria para lograrlo.
El truco que todos aprendimos en la escuela primaria consiste en descomponer el número en sus componentes más sencillos y manejar cada uno de éstos
en forma individual. De esta forma bastaría con tres dados de diez caras
cada uno para representar valores entre 1 y 1 000. Para ello habrá que asignar a cada dado una posición además de su valor y aprender a combinar
ambos factores para lograr la representación buscada.
Es decir, un sistema de numeración consta de dos componentes: una
base numérica y un esquema posicional. Para nuestro caso, el dado de diez
caras representa la base numérica (con diez diferentes valores: O a 9), y la
posición de cada dado con respecto al anterior define si le toca tomar el papel
de unidades, decenas o centenas.
Si se desea reducir el grado de complejidad técnica de la unidad de memoria, habrá que reducir a su mínima expresión la cantidad de valores a representar con cada posición, pero se pagará el costo de tener que aumentar el
número de posiciones, justamente porque entonces cada una vale menos.
Para aclarar lo anterior construiremos una unidad de memoria empleando dados de sólo dos caras (ya no de diez) para representar valores. ** Si a las
dos caras las llamamos Ay B, entonces con una moneda se podrán representar dos cosas diferentes: A o B (o una o la otra, pero no ambas a la vez, como
con cualquier moneda normal). Pero si se desea representar tres cosas diferentes habrá forzosamente que utilizar una moneda adicional, para entonces
poder escoger entre las siguientes cuatro posibilidades así:
A
A
B
B
A
B
A
B
Ésta es la primera posibilidad
Ésta es la cuarta
Si se estuvieran utilizando dos dados de diez caras (la primera de éstas
etiquetada con O,la segunda con 1 y así hasta la décima, etiquetada con 9),
entonces la situación aparecería así:
* En este contexto únicamente nos interesa la capacidad de mantener valores en sus caras,
dejando por completo fuera las consideraciones de suerte o aleatoriedad.
** Los "dados de dos caras" también se conocen como monedas.
2.4
Sistemabinario
o
O
O
O
1
2
Ésta es la primera posibilidad: valor O
Ésta es la segunda: valor 1
Ésta es la tercera: valor 2
2
7
Ésta es la vigésimo octava posibilidad: valor 27
9
9
8
9
Ésta es la nonagésimo novena: valor 98
Ésta es la centésima posibilidad: valor 99
63
Debe tenerse cuidado de no confundir las (cien diferentes) posibilidades
con el valor numérico que se les asigna: lo único que sucede es que los valores
que cada posibilidad representa comienzan desde cero, * y de allí la aparente
irregularidad de que, por ejemplo, la vigésimo octava posibilidad represente
el valor 27.
Si por el contrario se escogieran dados de 27 caras para representar valores, con uno de ésos bastaría para numerar esa cantidad de posibilidades
diferentes (una a la vez):
Cara-1
Cara-2
Ésta es la primera posibilidad: valor O
Ésta es la segunda: valor 1
Cara-26
Cara-27
Ésta es el vigésimo sexta: valor 25
Ésta es la vigésimo séptima posibilidad: 26
Es decir, el valor 11 se representaría
así:
Cara-12
porque a la Cara-1 se le asigna el valor cero, como ya se dijo.
Si con este sistema de dados de 27 caras fuera necesario representar el
valor 139, por ejemplo, habría que usar dos de éstos, y colocarlos uno al lado
del otro así:
Cara-6
Cara-5
* Recuérdese que no todas las culturas antiguas lograron comprender la enorme riqueza que
ofrece el número cero. En efecto, es gracias al cero que los sistemas de numeración se sostienen.
El cero no vale nada pero sí ocupa la primera cara de cada dado y puede simplemente separar
las posiciones de cada dígito sin añadir nada. Su valía consiste precisamente en su falta de valor
y en la presencia de la nada que implica.
64
Capítulo 2
,Cómo funciona una computadora'?
o bien
FIGURA 10.
Representación
en sistema unario.
El primer dado ("decenas de base 27") está en su sexta posición o cara
-que vale 5, porque la primera vale 0-, y el segundo ("unidades de base
27") está en la quinta posición -que vale 4-. Es decir:
139 = (5 x 27) + (4 x 1) = 135 + 4
Cara-6
Cara-5
Aunque esto pueda parecer confuso (¿cómo que cada cara del dado vale
uno menos que su posición?), en realidad emplea la misma lógica que todos
aprendimos en la escuela primaria.
En un sistema de numeración se escoge una base cualquiera (un dado
con ese número de caras) y luego se combinan posicionalmente tantos de esos
"dígitos" (o dados) como haga falta para llegar a representar el valor deseado, en el entendido de que cada uno vale base veces más que el que, está a su
derecha. Por tanto, cada nuevo dígito (o sea, la cara de ese nuevo dado) representa sucesivas potencias del valor base.
El sistema binario (í. e., con dados de dos caras) es casi el más sencillo que
existe para representar números. Este "casi" es porque la manera más simple para representar, por ejemplo, el número cuatro, es con el sistema unario
véase figura 10.
... pero habría algunos problemas técnicos al intentar representar el número diez millones. *
Dicho de otra forma, en el sistema binario se escoge el número dos como
la base de la numeración (así como en el decimal se escogió el diez), y se
representa un número cualquiera descomponiéndolo en las sucesivas potencias de dos que, sumadas, den como resultado el número en cuestión.
Por ejemplo, para escribir el valor 60 en binario habría que descomponerlo de la siguiente manera: una vez dos elevado a la quinta potencia, más una
vez dos elevado a la cuarta potencia, más una vez dos elevado a la tercera
* Esto se debe a que el sistema unario no es posicional, sino que cada "dígito" vale siempre lo
mismo (1), independientemente de la posición que ocupe. El sistema de números romanos, como
ejemplo similar, no es totalmente posicional, aunque sí representa un (pequeño) avance sobre el
unario; el Imperio Romano no se caracterizó precisamente por su superioridad en las matemáticas o en las minucias del intelecto.
2.4
Sistema binario
65
potencia, más una vez dos elevado al cuadrado, más cero veces dos elevado a
la primera potencia, más cero veces dos elevado a la cero potencia. En términos más sencillos sería:
porque
60
=
32 + 16 + 8 + 4
Es decir:
60
=
(111100)2
En el sistema decimal común y corriente se omite decir que la base es
diez, cosa que sí se dijo para el caso 111100 encerrándolo entre paréntesis y
poniendo el 2 como subíndice. Otra posibilidad es terminar la serie de unos
y ceros con la letra b:
(60)10= (111100)2= 111100b
El bit
Obsérvese que, para cada posición, el dígito binario puede tan sólo valer O
(la primera cara del dado) o bien 1 (la segunda cara). Como se dijo en el
capítulo anterior, la denominación "dígito binario" se abrevia comobit: binary
digit.*
El sistema de base 27 ya mencionado no es el más popular entre nosotros
(¿será porque no tenemos 27 dedos?), pero algunos sistemas de mayor uso
-además del decimal, por supuesto- son el binario (base 2), el octal (base
8) y el hexadecimal (base 16).
En hexadecimal se emplean dados de 16 caras:
O
1
Ésta es la primera posición: valor O
Ésta es la segunda: valor 1
9
A
B
Ésta es la décima: valor 9
Así se llama la undécima posición: valor 10
Ésta es la duodécima: valor 11
Ésta es la décimo tercera: valor 12
Ésta es la décimo cuarta: valor 13
Ésta es la décimo quinta: valor 14
Ésta es la décimo sexta posición: valor 15
C
D
E
F
* La palabra bit significa partecita en inglés, por lo cual el nombre resulta además muy
propio. El concepto matemático de bit como unidad de información es debido al doctor Claude
Shannon, y el nombre se le ocurrió a su colega de los Laboratorios Bell, John Turkey.
66
Capítulo 2
¿Cómo funciona una computadora?
Por lo que el valor 12 se expresa como CH (suele escribirse una h (o H) al
final de los números hexadecimales). Como antes, si se desea expresar el
número 125, habrá que usar varios dados:
125::: 7DH::: (1X 161) + (13 x 16°)::: 112 + 13
Igualmente,
2951::: B87H
porque
2951::: (11 X 162)+ (8.x 161)+ (1 X 161)
::: (11 x 256) + 128 + 7
::: 2816 + 128 + 7
Además, como 16 es la cuarta potencia de 2, existe una relación directa
que permite fácilmente convertir entre los números hexadecimales y los
binarios, porque a cada dígito hexadecimal siempre corresponden cuatro
dígitos binarios, acomodados como las sucesivas potencias 8-4-2-1. Es decir,
combinando la opción de seleccionar (mediante un 1) o no (mediante un O)
esa potencia, y haciendo luego la suma se puede pasar directamente entre la
base 16 y la base 2, como se ve a continuación.
Conversiones abreviadas
entre algunas bases
Potencias de dos
Por ejemplo, 2951 :::B87H ::: 101110000111b. Se ve más claro cómo se
obtuvo si se escriben los bits separados en grupos de cuatro comenzando por
la derecha: 101110000111.
2.4
Sistema binario
67
El sistema octal emplea dados de ocho caras: la primera de éstas vale O, la
segunda 1, y así hasta llegar a la octava, que vale 7. Por tanto, el valor 125 se
representa en octal como 1750 (la letra o al final significa octal), porque
125 = (l x 82) + <1X 81) + (Q x 8°)
64 + 56 + 5
Como 8 es la tercera potencia de 2, se puede entonces convertir directamente entre números octales y números binarios acomodando los bits por la
derecha en grupos de tres, de acuerdo con la serie de potencias 4-2-1, en
forma parecida al acomodo de cuatro en cuatro para el sistema hexadecimal.
Por tanto,
125 = 1750 = 1111101b
De nuevo, si se separan los bits por la derecha en grupos de tres, se verá
claramente cómo se obtuvieron: 001 111 101. (Los ceros a la izquierda se
omiten, como es la costumbre.)
Si ahora esos mismos bits se separan -siempre por la derecha para comenzar con las unidades- en grupos de cuatro (8-4-2-1), se llegará fácilmente al número 7D en hexadecimal:
125 = 0111 1101
7D
Teoría de la información
Existen diferentes métodos para convertir un valor numérico de una base
a otra, aunque ya no se explicarán aquí, porque nuestro tema sigue siendo
la memoria de la computadora. En [BROG95] y [TUCB94] se trata con más
detalle estos temas, y además son textos recomendables sobre computación
en general.
Todoeste largo análisis surgió de la necesidad de almacenar números en la
forma más sencilla posible, que resulta ser la binaria, porque emplea "dados"
de dos caras (bits), que en una computadora pueden construirse con dispositivos eléctricos o electrónicos que asumen una sola de dos posiciones posibles:
0/1, o apagado/encendido, o no conduce/conduce, etcétera. En las computadoras se escogióel sistema binario para representar números justamente porque
así se simplifica al máximo el diseño electrónico de sus componentes.
Por otro lado, un resultado teórico debido a Shannon especifica que el
sistema binario es suficiente para representar cualquier cantidad de información. Esta propuesta constituye la base del campo llamado teoría de la
información, del que se dará un ejemplo sencillo. Si se considera el problema de averiguar la edad de una persona, en lugar de preguntárselo directamente, podría intentarse encontrar un método general y, al mismo tiempo,
definir ciertos conceptos nuevos. Se podría preguntar: ¿tienes menos de cincuenta años?, y la respuesta sólo podría ser sí o no. A partir de esa respuesta
podrían hacerse más "preguntas binarias" (cuya contestación sea sí o no)
hasta encontrar el dato que se busca. Se dice que la cantidad de información que un dato contiene se mide por el número mínimo de preguntas
binarias requeridas para averiguarlo con exactitud.
68
Capítulo 2
,Cómo funciona una computadora'?
Unidades binarias de
medida
Este número mínimo fue acotado y medido por Shannon, pero ya no tiene
por qué preocuparnos aquí. Lo que sí interesa es entender que ese posible
cero o uno (ese bit) será, de aquí en adelante, la unidad mínima de información. El artículo [BHAR87] contiene una explicación introductoria a la
teoría de la información y a los resultados de Shannon.
Por comodidad, los bits suelen trabajarse en grupos de ocho. Cada uno de
estos pequeños grupos recibe el nombre de byte (binary term). Los bytes, a
su vez, forman grupos de 1024,y cada uno de éstos se conocecomoun Kilobyte
(KB).
Se escogen esos números porque 8 = 23 Y 1024 = 210• Finalmente, cerca
de un millón de bytes constituyen un Megabyte (MB). El número exacto es
220 = 1 048 576 bytes.
Para terminar el capítulo es importante mencionar que prácticamente
todas las computadoras comerciales (sin importar la marca o el tipo) en principio siguen el modelo de von Neumann aquí descrito. Esto no quiere decir,
sin embargo, que la programación se haga de manera tan burda como la
mostrada; de hecho, ningún programador trabaja así, sino que emplea los
lenguajes de programación y las facilidades proporcionadas por la programación de sistemas mediante ensambladores, compiladores y sistemas
operativos, que se estudiarán en los capítulos siguientes.
PALABRAS Y CONCEPTOS CLAVE
En esta sección se agrupan las palabras y conceptos de importancia estudiados en el
capítulo, para que el lector pueda hacer una autoevaluación que consiste en ser capaz
de describir con cierta precisión lo que cada término significa, y no sentirse satisfecho
sino hasta haberlo logrado. Se muestran en el orden en que se describieron o se mencionaron.
PROGRAMA
INSTRUCCIONES
MODELO DE VON NEUMANN
PROGRAMA ALMACENADO
CELDA DE MEMORIA
VALOR
DIRECCIÓN EN MEMORIA
APUNTADOR
CODIFICACIÓN
"DICCIONARIO ELECTRÓNICO"
MNEMÓNICOS
LENGUAJE DE MÁQUINA
PROGRAMA FUENTE
PROGRAMA OBJETO
CARGA EN MEMORIA
CICLO DE FETCH
HARDWARE
SOFTWARE
CONTADOR DE PROGRAMA
EJECUCIÓN DE UN PROGRAMA