Sie sind auf Seite 1von 31

Tema 1: Conceptos Básicos

1 Conceptos Previos
La informática es la ciencia que estudia el procesamiento automático de la información.
Para llevar a cabo ese procesamiento se utiliza el computador, que es una máquina, generalmente
electrónica, que procesa información siguiendo las instrucciones de un programa.
Los computadores pueden manejar grandes volúmenes de datos y realizar gran número de
operaciones en un corto espacio de tiempo.
Los computadores suelen ser de propósito general. Es decir, el mismo computador puede utilizarse
para realizar diferentes tareas (p.e. crear un documento de texto, servir páginas web, hacer cálculos
matemáticos etc... ). Pueden existir computadores de propósito específico (p.e. el computador que
gobierna una lavadora, un vehículo, etc...), pero incluso estos computadores de fin específico,
podrían realizar tareas radicalmente distintas con sólo cambiar las instrucciones de los programas
que ejecutan.
Para entender qué es un programa habría que definir primero algoritmo. Un algoritmo es la
descripción precisa de los pasos que permiten resolver un determinado problema. Por ejemplo, los
pasos a seguir para calcular quién es el alumno que ha sacado la nota más elevada en un examen
(supuesto que el computador ya contiene la lista de alumnos con el nombre y nota de cada uno)
podrían codificarse mediante el siguiente algoritmo:

Suponer que la nota máxima del examen es -1


Por cada alumno de la lista
Si su nota es mayor que la nota máxima que se haya encontrado en ese momento
la nota máxima por el momento, es la de ese alumno
el alumno que, de momento, tiene la nota máxima es ese
Pasar al siguiente alumno de la lista
Mostrar en la pantalla el alumno que tras explorar todos tiene la nota máxima

Ilustración 1: Ejemplo de Algoritmo.

Como se puede observar contiene 7 pasos, cada uno de ellos es lo suficientemente preciso, como
para que sea improbable que dos personas los entiendan de forma diferente.
Un programa es la codificación de un algoritmo mediante un lenguaje de programación. El
algoritmo de la ilustración anterior, está codificado en el lenguaje que utilizamos cotidianamente, al
que nos referiremos a partir de ahora como lenguaje natural. Pero los computadores, al menos a
fecha de hoy, no entienden el lenguaje natural. Por tanto, es necesario codificar las instrucciones de
los algoritmos en un lenguaje que sí entiendan. Existen muchos lenguajes de este último tipo, y se
conocen como lenguajes de programación.
Un lenguaje de programación, por tanto, es un conjunto de instrucciones y reglas sintácticas que
permiten codificar un programa de forma inteligible para el computador.
En la Ilustración 2 se puede ver el mismo algoritmo de la ilustración anterior ya codificado en un
determinado lenguaje de programación. Cada elemento en el código no es casual, sino que se rige
por las reglas sintácticas de ese lenguaje. Por ejemplo, se ve que todas las llaves abiertas "{" tienen
una correspondiente llave cerrada "}". Cada linea representa una instrucción, en algunas hay

Apuntes descargados de wuolah.com


palabras clave, como var, new, Array, for o if que el computador sabe interpretar adecuadamente.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"


"http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<TITLE>Ejemplo alumno con la nota maxima</TITLE>
</head>

<body>
<script language="javascript" type="text/javascript">

var listaNotas = new Array(5);

listaNotas[0] = {nombre: "Pepe", nota: 5};


listaNotas[1] = {nombre: "Juan", nota: 4.5};
listaNotas[2] = {nombre: "Ana", nota: 6};
listaNotas[3] = {nombre: "Luis", nota: 7};
listaNotas[4] = {nombre: "Pedro", nota: 5};

var notaMaxima=-1;
var alumnoMaximo="";

for (i=0; i<5; i++){


if (listaNotas[i].nota>notaMaxima){
notaMaxima=listaNotas[i].nota;
alumnoMaximo=listaNotas[i].nombre;
}
}

document.write("Solución: "+alumnoMaximo);
</script>
</body>

</html>

Ilustración 2: Algoritmo anterior codificado en el lenguaje de programación JavaScript. La


parte sombreada es la que se corresponde casi línea a línea con el algoritmo. Se suponen 5
alumnos nada mas.

Los lenguajes de programación puedes ser más fáciles entender por el programador (por un
humano) y entonces se dice que es un lenguaje de alto nivel, o más difíciles de entender por un
humano, y entonces se habla de lenguajes de bajo nivel.
El lenguaje de más bajo nivel, es el llamado lenguaje máquina. El lenguaje máquina se caracteriza
porque sólo utiliza ceros y unos en su codificación, que se corresponden con dos estados que
pueden tener distintos componentes físicos del computador. Por ejemplo, por un conductor puede
pasar -o no- corriente eléctrica, o un CD puede tener -o no- una cavidad en un determinada
posición, o un disco puede tener magnetismo remanente en uno u otro sentido en una posición del
mismo, o una de las obsoletas tarjetas perforadas, puede tener -o no- una posición perforada. Cada
uno de esos dos estados puede ser representarse mediante un 1 y un 0 respectivamente (o
viceversa).
Los computadores modernos están basados en millones de estos componentes que pueden tomar
dos estados posibles, y el lenguaje máquina de un determinado computador (cada computador

-2-

BNext, tu cuenta sin banco.


tiene el suyo propio que normalmente no vale para otros modelos de computador) es
directamente comprensible por dicho computador, sin necesidad de una traducción intermedia.
Sin embargo, los lenguajes de alto nivel siempre requieren un proceso de traducción que de una
forma u otra de lugar a un conjunto de instrucciones inteligibles por el computador, y por tanto en
lenguaje máquina.
En un computador se distinguen dos partes fundamentales: el hardware que es la parte física del
mismo (circuitería, periféricos etc...), y el software que son el conjunto de programas que corren
sobre el mismo.

2 Representación de la Información
Un computador sólo es capaz de entender de forma “directa” información que le viene codificada
de forma binaria (i.e. a través de ceros y unos). Cada uno de estos ceros o unos se conocen como
bits. Una cifra o ristra binaria compuesta por 8 ceros y/o unos se conoce como byte. En un
computador la información binaria siempre ocupa un determinado número de bytes, o lo que es lo
mismo, todas las cifras o ristras binarias tienen una longitud en bits, que es múltiplo de 8.
Los datos que procesa un computador pueden ser de distintos tipos: numéricos y cadenas de
caracteres entre otros. Las cadenas de caracteres sirven para representar texto. Los datos numéricos
pueden a su vez ser de distintos tipos: enteros sin signo, enteros con signo y números reales
típicamente. A su vez cada uno de estos tipos puede ser representado en binario de distintas formas
o codificaciones.

2.1 Representaciones numéricas en una base genérica


Para entender cómo los computadores codifican los números en sistema binario (en base 2),
conviene repasar cómo representar la información en cualquier base.
Cuando nos dan una cifra entera en decimal (base 10), por ejemplo 647, su verdadero significado
podría decirse que es 6*102+4*101+7*100. Es decir, cada cifra tiene un significado en función de su
posición, y ese significado viene dado por elevar la base (en este caso 10) al exponente
correspondiente a dicha posición.
En el sistema decimal hay 10 dígitos que van del 0 al 9. En cualquier base, por ejemplo B, los
dígitos pueden tomar B valores, que van desde 0 hasta B-1.
Por ejemplo, si quisiéramos numerar en base 5, lo dígitos que podríamos utilizar sólo podrían estar
entre el 0 y el 4. La cifra 647, por tanto es imposible que se dé si utilizamos base 5. Una cifra que
por ejemplo si es posible en base 5, es 342, la cual significaría en decimal 3*52+4*51+2*50=97
Por tanto, ya tenemos un mecanismo que dado un número en una base cualquiera nos permite
traducirlo al sistema decimal:

Sean cncn-1...c1c0 las cifras en base B de un número, entonces la


representación decimal de dicho número es Bncn+Bn-1cn-1...+B1c1+B0c0.

Nos pueden plantear el problema inverso: dado un número en decimal pasarlo a una determinada
base B. Supongamos el número 97 en decimal que queremos representarlo en base 5. El
procedimiento que se sigue en ese caso es el de divisiones sucesivas por la base:

-3-

BNext, tu cuenta sin banco.


97 5
2 19 5
4 3

Ilustración 3: Paso del número 97 a base 5 por el método de las divisiones sucesivas.

Como muestra la figura, se va dividiendo el número por la base a la que queremos pasarlo,
repitiendo la misma operación con el cociente así obtenido. Y eso lo hacemos hasta que lleguemos a
un cociente menor que la base (en el ejemplo hemos parado porque el cociente 3 es menor que 5).
Después, se toma el último cociente: 3, y se concatenan los restos de las divisiones desde abajo
hacia arriba: 4 y 2 (ver flechas de la ilustración). Por tanto, 342 en base 5 es lo mismo que 97 en
base 10.
Esto es fácil de ver, ya que las divisiones sucesivas lo que realmente nos dicen es que
97 = 5*19 + 2 = 5*( 5*3 + 4) + 2 = 5*5*3 + 5*4 + 2 = 3*52+4*51+2*50=97
Ahora utilizaremos estos dos conceptos para representar un número en las bases 2, 8 y 16, muy
utilizadas en el ámbito de los computadores.

2.2 Representación binaria de los datos de tipo entero sin signo


Los números binarios, representan cantidades utilizando base 2. Por tanto, según lo visto en el
apartado anterior sus cifras sólo pueden tomar 2 valores: 0 ó 1. Claramente los números binarios se
adaptan perfectamente al tipo de representación física de la información que utilizan los
computadores.
Dado un número en binario, por ejemplo, 10011101 podemos pararlo a decimal utilizando el mismo
método que utilizamos en el apartado anterior para pasar el ejemplo en base 5 a decimal. Por tanto,
se trata de:
1*27+0*26+0*25+1*24+1*23+1*22+0*21+1*20=
128+0+0+16+8+4+0+1=157
De la misma forma, si nos hubiesen pedido el problema inverso: pasar a binario el número decimal
157, hubiéramos procedido con el método de las divisiones sucesivas, en este caso entre 2, como
muestra la siguiente ilustración.
Como ya se ha comentado las cifras ocuparán un número determinado de bytes. Por ejemplo, un
entero de longitud de 1 solo byte podría tomar los valores señalados en la Tabla 1, que como se ve
oscilan siempre (en decimal) entre 0 y 2n-1, donde n es el número de bits correspondiente a la
longitud de la cifra. Por ejemplo, el número máximo que se puede representar con 2 bytes es 216-1 =
65535.
La razón es clara, con n cifras binarias el número de combinaciones de ceros y unos que se pueden
hacer es 2n (combinaciones con repetición de 2 elementos tomados de n en n). Si esas 2n
combinaciones las empezamos a numerar desde cero, la primera sería 0 y la última 2n-1.
En la tabla también se vé que la cifra más baja del rango es una concatenación de n ceros, mientras
que la más alta es una concatenación de n unos.

-4-
157 2
1 78 2
0 39 2
1 19 2
1 9 2
1 4 2
0 2 2
0 1

Ilustración 4: Paso del número 157 a base 2 por el método de las divisiones sucesivas.

Binario Significado Decimal Rango


7 6 5 4 3 2 1 0
0000 0000 0*2 +0*2 +0*2 +0*2 +0*2 +0*2 +0*2 +0*2 0 0
7 6 5 4 3 2 1 0
0000 0001 0*2 +0*2 +0*2 +0*2 +0*2 +0*2 +0*2 +1*2 1
0000 0010 0*27+0*26+0*25+0*24+0*23+0*22+1*21+0*20 2
7 6 5 4 3 2 1 0
0000 0011 0*2 +0*2 +0*2 +0*2 +0*2 +0*2 +1*2 +1*2 3
7 6 5 4 3 2 1 0
0000 0100 0*2 +0*2 +0*2 +0*2 +0*2 +1*2 +0*2 +0*2 4
….......................................
1111 1101 1*2 +1*26+1*25+1*24+1*23+1*22+0*21+1*20
7
253
7 6 5 4 3 2 1 0
1111 1110 1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +0*2 254
1111 1111 1*27+1*26+1*25+1*24+1*23+1*22+1*21+1*20 255 255 = 28-1

Tabla 1: Cifras binarias para un entero sin signo de longitud 1 byte.

2.3 La representación octal y hexadecimal


La representación binaria vista tiene la ventaja de que es comprendida y representable en un
computador de forma directa, pues es fácil encontrar dispositivos físicos que tengan dos estados y
asignar a cada uno de ellos el cero y el uno.
Sin embargo, el sistema binario resulta engorroso para un operador humano quien fácilmente puede
equivocarse al leer o escribir un uno donde quería leer o escribir un cero, y viceversa.
Antes de que existieran los lenguajes de programación modernos, los programadores tenían que
codificar sus programas a través de números o códigos numéricos en binario que tenían un
significado especial para la máquina. Por ejemplo, un determinado código numérico podría tener el
significado de leer un dato de la memoria, otro código numérico podría significar que hay que
incrementar el valor de un dato una unidad, otro código que hay que sumar el dato que esta en tal
sitio con el que está en este otro, etc... Estos programas se codificaban entéramente en binario (en
un principio utilizando tarjetas perforadas) y un error de transcripción en un cero/uno de más o de

-5-

BNext, tu cuenta sin banco.


menos era fatal para el funcionamiento del programa. Por eso se empezaron a utilizar los códigos en
octal (base 8) y en hexadecimal (base 16).
Tanto la base 8 como la 16 tienen la ventaja de ser múltiplos de 2, por lo que el paso de estas bases
a binario y desde binario resulta, como veremos, muy sencillo.
La codificación ocal, lógicamente, utiliza únicamente los dígitos que van del 0 al 7, así el número
10 en octal es el 8 en decimal, el 11 es el 9 etc.
La codificación hexadecimal requiere de 16 dígitos para representar los números que van del 0 al
15. Como no hay dígitos decimales para los números del 9 al 15 se toman las primeras letras del
alfabeto para ese fin. Por ejemplo, la A representa el 10, la B el 11 y la F el 15. El número 10 en
hexademial sería el 16 en decimal.
A continuación se muestran una tabla que representa los números del 0 al 59 en decimal, octal y
hexadecimal:
DEC OCT HEX DEC OCT HEX DEC OCT HEX
0 0 0 20 24 14 40 50 28
1 1 1 21 25 15 41 51 29
2 2 2 22 26 16 42 52 2A
3 3 3 23 27 17 43 53 2B
4 4 4 24 30 18 44 54 2C
5 5 5 25 31 19 45 55 2D
6 6 6 26 32 1A 46 56 2E
7 7 7 27 33 1B 47 57 2F
8 10 8 28 34 1C 48 60 30
9 11 9 29 35 1D 49 61 31
10 12 A 30 36 1E 50 62 32
11 13 B 31 37 1F 51 63 33
12 14 C 32 40 20 52 64 34
13 15 D 33 41 21 53 65 35
14 16 E 34 42 22 54 66 36
15 17 F 35 43 23 55 67 37
16 20 10 36 44 24 56 70 38
17 21 11 37 45 25 57 71 39
18 22 12 38 46 26 58 72 3A
19 23 13 39 47 27 59 73 3B
Tabla 2: Lista de los números del 0 al 59 en decimal (DEC), octal (OCT) y hexadecimal (HEX).
Para cambiar de base octal o hexadecimal a binario y viceversa podemos utilizar los procedimientos
explicados en la sección anterior. Sin embargo, aprovechando que 8 y 16 son múltiplos de 2 el
procedimiento se puede simplificar notablemente:
• Supongamos un número en octal, por ejemplo 5721, para pasarlo a binario basta pasar a

-6-

BNext, tu cuenta sin banco.


binario cada uno de sus dígitos, utilizando 3 dígitos binarios para cada uno:
5 => 101 7 => 111 2 => 010 1 => 001
Por lo que el número 5721 en octal es el 101 111 010 001 en binario.
• De la misma forma, pasar de binario a octal es inmediato, basta con agrupar en grupos de 3
dígitos binarios, empezando a contar desde la derecha. Así el número 1101001 en octal
sería:
1-101-001 => 151
• El caso hexadecimal es similar. Si se tiene por ejemplo el número A51B, basta con traducir a
decimal cada uno de sus dígitos, pero esta vez usando 4 dígitos:
A => 1010 5 => 0101 1 => 0001 B => 1011
Por lo que el número hexadecimal A51B es el 1010 0101 0001 1011 en binario.
Para pasar de binario a hexadecimal se divide la ristra binaria en grupos de 4 empezando a
contar desde la derecha, y cada grupo se pasa a hexadecimal. Así el número 10 1011 0001 es
el 2B1 en hexadecimal.
Esta facilidad de conversión con el sistema binario hizo que estos dos sistemas de numeración se
utilizasen para representar códigos binarios disminuyendo el riesgo de equivocarse. El código octal
ha ido perdiendo influencia con el tiempo, y en la actualidad es el hexadecimal el que se utiliza para
este fin, y en ambientes muy específicos relacionados con la electrónica digital en los que trabaja
directamente con el microprocesador.

2.4 Representación binaria de los datos de tipo entero con signo


La forma más inmediata de representar números negativos sería utilizar uno de los bits como bit de
signo. Este bit, por ejemplo, cuando valiese cero significaría que el número es positivo y cuando
valiese uno que es negativo. Esta representación se conoce como enteros con signo y magnitud.
Por ejemplo, tenemos el número binario sin signo 001 0110, que en decimal es 16+4+2=22. El
número 22 negativo en la representación con signo y magnitud consistiría en simplemente poner un
uno delante indicando que es negativo: 1001 0110. Por el contrario, 0001 0110 representaría al 22
positivo. En ambos ejemplo el signo es el primer bit de la izquierda, y la magnitud está formada
por los otros siete: 001 0110
Como se puede observar el dígito más a la izquierda (el dígito más significativo) se deja de
interpretar como un dígito numérico, para interpretarlo como signo, por lo que lógicamente la
mayor magnitud posible es menor que la podíamos obtener en la sección anterior, cuando los
enteros no tenían signo veíamos que un byte podíamos llegar hasta 255, pero como se puede ver en
la siguiente tabla, para enteros con signo y magnitud de 2 bytes sólo llegamos hasta 127
(aproximadamente la mitad).

-7-

BNext, tu cuenta sin banco.


Binario Significado Decimal Rango
6 5 4 3 2 1 0
1111 1111 -(1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +1*2 ) -127 -127 = - (27-1)
1111 1110 -(1*26+1*25+1*24+1*23+1*22+1*21+0*20) -126
6 5 4 3 2 1 0
1111 1101 -(1*2 +1*2 +1*2 +1*2 +1*2 +0*2 +1*2 ) -125
…....................................
1000 0001 -(0*2 +0*25+0*24+0*23+0*22+0*21+1*20)
6
-1
6 5 4 3 2 1 0
1000 0000 -(0*2 +0*2 +0*2 +0*2 +0*2 +0*2 +0*2 ) 0
6 5 4 3 2 1 0
0000 0000 +(0*2 +0*2 +0*2 +0*2 +0*2 +0*2 +0*2 ) 0
0000 0001 +(0*26+0*25+0*24+0*23+0*22+0*21+1*20) 1
….......................................
0111 1101 +(1*2 +1*25+1*24+1*23+1*22+0*21+1*20)
6
125
6 5 4 3 2 1 0
0111 1110 +(1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +0*2 ) 126
0111 1111 6 5 4 3
+(1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +1*2 ) 2 1 0
127 127 = + (27-1)

Tabla 3: Cifras binarias para un entero con signo y magnitud de longitud 1 byte.
Intuitivamente, lo que ha pasado es que se han destinado la mitad de las cifras (las que empiezan
por uno) a representar a los números negativos, y la otra mitad (los que empiezan por cero) a
representar los números positivos.
El número negativo más pequeño que se pude representar utilizando n cifras es – (2n-1-1). 2n-1 es
precisamente la mitad de 2n, y el -1, igual que antes es porque empezamos a contar desde cero en
lugar de desde uno.
De la misma manera, el número positivo más grande que se pude representar utilizando n cifras es
(2n-1-1). 2n-1 es la mitad de 2n, y el -1, nuevamente es porque empezamos a contar desde cero en
lugar de desde uno.
La representación son signo y magnitud presenta dos problemas:
1. Hacer restas entre números binarios requiere un algoritmo distinto que para las sumas, por lo
que para cada cosa se necesitan circuitos electrónicos diferentes.
2. Como se aprecia el número cero tiene dos representaciones posibles, por lo que no sólo se
desperdicia una cifra que podía valer para representar otro número, sino que además a la
hora de hacer operaciones se vuelven más complicadas porque hay que tener en cuenta este
hecho.
Por ello, aparece la representación binaria con signo conocida como complemento a 1. En esta
representación el bit más significativo sigue representando el signo ( 0 positivo, 1 negativo), y la
magnitud esta codificada de manera que los ceros se han sustituido por unos y viceversa. Por
ejemplo:
1. El número de un byte 0010 0101 es un número positivo porque el primer bit es un cero, por
lo tanto la magnitud viene dada por los siete bits restantes 010 0101 que representan el
número decimal 32+4+1=37.
2. Sin embargo, el número de un byte 1010 0101 es un número negativo porque empieza por 1,
para saber de qué número en decimal se trata hay que sustituir los ceros por unos y
viceversa, en el ejemplo se obtendría 0101 1010. Ese número binario en decimal es

-8-
64+16+8+2 = 90, por lo tanto se trata del “-90” en decimal.
La siguiente tabla muestra para números de longitud de 1 byte el rango posible de enteros a
representar en codificación complemento a 1.
Binario Significado Decimal Rango
6 5 4 3 2 1 0
1000 0000 -111 1111(binario)=(1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +1*2 ) -127 -127 = - (27-1)
1000 0001 -111 1110(binario)=-(1*26+1*25+1*24+1*23+1*22+1*21+0*20) -126
1000 0010 -111 1101(binario)=-(1*26+1*25+1*24+1*23+1*22+0*21+1*20) -125
…....................................
1111 1110 -000 0001(b=-(0*26+0*25+0*24+0*23+0*22+0*21+1*20) -1
1111 1111 -000 0000(b=-(0*26+0*25+0*24+0*23+0*22+0*21+0*20) 0
0000 0000 +(0*26+0*25+0*24+0*23+0*22+0*21+0*20) 0
6 5 4 3 2 1 0
0000 0001 +(0*2 +0*2 +0*2 +0*2 +0*2 +0*2 +1*2 ) 1
….......................................
0111 1101 +(1*26+1*25+1*24+1*23+1*22+0*21+1*20) 125
6 5 4 3 2 1 0
0111 1110 +(1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +0*2 ) 126
0111 1111 +(1*26+1*25+1*24+1*23+1*22+1*21+1*20) 127 127 = + (27-1)

Tabla 4: Cifras binarias para un entero de longitud 1 byte codificado en complemento a 1.


Como se puede observar se mantiene el problema que tenía la representación por signo y magnitud,
por la que el número cero tenía dos representaciones
Sin embargo, con esta codificación la operación de resta se hace casi igual que la de suma. Por
ejemplo, para sumar 0000 1011(b + 0000 1110(b = 11 + 14 = 25, se procedería así:

0 0 0 0111011 1
+00001110
00011001

donde los unos en superíndice indican el acarreo (por ejemplo: 1+1 = 10(b se pone un cero por
debajo de la raya horizontal, y el 1 es el acarreo o “las que me llevo”).
Si hacemos 11 – 14 basta también con sumar el 11 al “-14”, es decir 0000 1011(b + 1111 0001(b

0 0 0 0 1 01111
+11110001
11111100

El resultado 1111 1100, al cambiar los ceros por unos es 0000 0011, es decir 3, por tanto menos 3,
que efectivamente es el resultado de hacer 11 – 14. En general cuando el resultado de la resta es
negativo basta sumar ambos números como hemos visto en este ejemplo, pero la cosa cambia
cuando el resultado es positivo.
Si hacemos 14 – 11 al sumar el 14 con el “-11”, es decir 0000 1110(b + 1111 0100(b :

-9-

BNext, tu cuenta sin banco.


00001110
+11110100
00000010

Es decir 2, cuando tenía que haber dado 3. En general, cuando el resultado de la resta es positivo,
nos sale una unidad menos de la que tenía que salir. Esto nos lleva a otra representación binaria que
soluciona este problema: el complemento a 2.
Para representar un número negativo en complemento a 2, primero lo representamos en
complemento a 1, y a continuación se le suma 1. Por ejemplo, el número 0010 0101 igual que en
casos anteriores es positivo por empezar por cero, y los otros siete dígitos 010 0101 codifican el
número decimal 37.
Pero 1010 0101 es un número negativo por empezar por uno, luego para saber de qué número se
trata tenemos que tener en cuenta que se le ha sumado 1, por tanto buscamos el número
inmediatamente anterior: 1010 0100 y en ese número hacemos el cambio de ceros por unos: 0101
1011 que en decimal es 64+16+8+2+1=91, por tanto es el -91.
Si hacemos la tabla que representa todos los números posibles en complemento a 2 para una
longitud de un byte tenemos:
Binario Significado Decimal Rango
1000 0000 0111 1111(complemento a 1)=-1000 0000(b=-1*27 -128 -128 = - 27
1000 0001 1000 0000(c1=-0111 1111(b -127
1000 0010 1000 0001(c1=-0111 1110(b -126
…....................................
1111 1110 1111 1101(c1=-0000 0010(b -2
1111 1111 1111 1110(c1=-0000 0001(b -1
0000 0000 +(0*26+0*25+0*24+0*23+0*22+0*21+0*20) 0
6 5 4 3 2 1 0
0000 0001 +(0*2 +0*2 +0*2 +0*2 +0*2 +0*2 +1*2 ) 1
….......................................
0111 1101 +(1*26+1*25+1*24+1*23+1*22+0*21+1*20) 125
6 5 4 3 2 1 0
0111 1110 +(1*2 +1*2 +1*2 +1*2 +1*2 +1*2 +0*2 ) 126
0111 1111 +(1*26+1*25+1*24+1*23+1*22+1*21+1*20) 127 127 = + (27-1)

Tabla 5: Cifras binarias para un entero de longitud 1 byte codificado en complemento a 2.


Como se puede observar ahora el cero sólo tiene una representación, por lo que se ha ganado la
posibilidad de representar un número negativo mas: el -128. Pero además todas las restas se pueden
realizar como sumas, con lo que el mismo circuito electrónico puede servir para realizar ambas
operaciones.
Por ejemplo, 11 – 14 se hace sumando el 11 al “-14”, es decir 0000 1011(b + 1111 0010(b

-10-

BNext, tu cuenta sin banco.


0 0 0 0 1 01 1 1
+11110010
11111101

El resultado 1111 1101 en complemento a 2 es 1111 1100 en complemento a 1, por lo que es el


menos 0000 0011, es decir el -3 (11-14=-3).
Pero el caso en el que el resultado fuese positivo también sale directamente. Por ejemplo, 14 -11

01010101111 1 0
+11110101
100000011

El uno más significativo se pierde, por ser el límite de la longitud de palabra 8 bits (sería el noveno
bit...) por lo que efectivamente el resultado es 0000 0011, es decir 3 en decimal.
Otras posibles representaciones para los enteros son la representación sesgada y la BDC, en los que
las operaciones no son tan simples como en el complemento a 2.

2.4.1 La representación sesgada


La denominada sesgada, en la que no hay bit de signo debido a que se suma a todos los números
una cantidad constante (i.e. un sesgo) de forma que ninguno se representa como negativo. Para el
caso de una longitud de un byte el sesgo sería 128 = 1000 0000 en binario. Así el número 0010 0101
= 32 + 4 + 1 =37, no es realmente el 37, sino 37-128 = -91, mientras que el 1010 0101 = 128 + 32 +
4 + 1 = 128 + 37 es en realidad el 37.

2.4.2 BCD (o Binary Coded Decimal)


El BCD puede ser extendido o bien empaquetado. En el BCD extendido se utiliza un byte para
representar cada dígito decimal, por lo que cada byte puede tomar sólo los valores que van desde
0000 0000 a 0000 1001 (de 0 a 9 en decimal).
Claramente, de esta forma se pierden muchas combinaciones binarias, pues un byte puede
representar los números que van del 0 al 255, y sólo se están aprovechando las 10 combinaciones
que van de 0 a 9. Por ello, aparece el BCD empaquetado. En esta representación los dígitos binarios
se agrupan de 4 en 4, de forma que cada grupo puede tomar valores entre 0000 y 1001 (de 0 a 9 en
decimal). Por ejemplo, el número BCD de 2 bytes 1001 0101 0010 0101 es el 9525, pues los 4
primeros dígitos representan el 9 los 4 siguientes el 5, los 4 siguientes el 2 y los 4 últimos el 5. Para
hacer BCD empaquetado con signo se reserva el último cuarteto a tal fin, de manera que si el
número acaba en 1100 se interpreta como positivo, y si acaba en 1101 como negativo. Por ejemplo:
1001 0101 0010 1100 es el +952, y el 1001 0101 0010 1101 es el -952.

-11-

BNext, tu cuenta sin banco.


2.5 Números reales
La forma más común de representar cantidades que no son exactas y tienen por tanto decimales, es
la Notación exponencial ( o científica o en coma flotante). En esta notación cada número consta de
dos campos:
• La mantisa M
• El exponente e
e
de tal forma que el número que se está representando se obtiene como M * B , donde B es la base.
Tanto la mantisa como el exponente tienen su propio signo cada una, y la base es siempre la misma.
Por tanto, estamos ante el mismo tipo de representación que hemos visto muchas veces en las
calculadoras científicas, donde por ejemplo el número 3.456 E+02 le leemos como 3.456*102, ya
que en las calculadoras se asume que la base es 10.
Con este tipo de notación es posible representar tanto:
1. Números con un valor absoluto muy grande (i.e. tendentes a los infinitos positivos y
negativos) mediante un exponente positivo muy grande.
2. Números con un valor absoluto muy pequeños (i.e. cercanos al cero) mediante un
exponente negativo muy grande.
En las computadoras la notación exponencial más extendida es la que sigue la norma IEEE 754, en
la que la base es 2, y se utilizan 32 bits, de los cuales:
1. El primero es el signo de la mantisa (S en la figura) que vale 0 si el número (la mantisa) es
mayor que cero y 1 en caso contrario).
2. Los ocho siguientes son el exponente, que aparentemente siempre es positivo debido que
utiliza la representación sesgada con sesgo 127
3. Los 23 siguientes bits son la mantisa.
s e m
31 30 23 22 0
Ilustración 5: Estructura de un número en coma
flotante según la norma IEEE 754.
La mantisa se interpreta de forma que la coma está a la derecha del bit más significativo.
Por ejemplo, si tenemos el número binario
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
1 1 0 0 0 0 1 0 1 1 1 0 1 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0

1. Es negativo porque el bit 31 es 1


2. El exponente 10000101 = 128+4+1 está codificado en exceso 127, luego en realidad es un
exponente, en este caso, positivo igual a 128+4+1-127 = 6
3. La mantisa es 110 1101 0100 0000 0000 0000, luego poniendo la coma en su sitio realmente
se trata del 1,10 1101 0100 0000 0000 0000 = 20+2-1+2-3+2-4+2-6+2-8= 1,7070312500
Por tanto, se trata del número -1,7070312500 * 26 = -109.25

-12-
2.6 Representación del texto o cadenas de caracteres
Un carácter es un símbolo cualquiera, lo que incluye a:
• Las letras, tanto en mayúsculas como en minúsculas.
• Los propios dígitos decimales.
• Los signos de puntuación ( puntos, comas, puntos y coma, etc.)
• Y caracteres de control, los cuales no se visualizan en la pantalla o en el papel de la
impresora, pero tienen una finalidad concreta, como son: el carácter que indica que finaliza
una línea, o el que indica que finaliza un fichero, o el que indica un tabulador etc.

2.6.1 Codificación de 8 bits: ASCII y ASCII extendido


La forma tradicional de representar los caracteres ha sido a través de un código de longitud 1 byte.
Dos códigos que siguen este criterio es el EBCDIC y el ASCII. Ambos códigos nacen en los años
60.
El EBCDIC (Extended Binary Coded Decimal Interchange Code) se utilizaba en grandes máquinas
de IBM. El ASCII (American Standard Code for Information Interchange) ha tenido una mayor
difusión y se sigue utilizando mucho en nuestros días.
En el código ASCII original sólo se utilizan los 7 últimos bis del byte, desperdiciándose el primer
bit. Esto es debido a que de los 256 posibles caracteres que se podrían haber codificado con 8 bits,
en aquellos tiempos sólo se codificaron 128, ya que sólo se dio soporte al alfabeto inglés.
La tabla de caracteres ASCII tiene la siguiente estructura:
1. Los caracteres del 0 al 31 son caracteres de control. No son imprimibles/visualizables, y la
mayoría de ellos ya no se utilizan en la actualidad, ya que se corresponden con funciones
pensadas para impresoras antiguas y teletipos. Algunos ejemplos de aquellos que todavía se
utilizan son: El 9=tabulador, el 10 = Salto de Línea, el 13 = Retorno de carro, el 27 =
Escape.
2. Del 32 al 126 son caracteres imprimibles que se dividen en:
1. 32 al 47, diversos signos, algunos de los cuales son de puntuación: espacio en blanco, !,
“, #, $, %, &, ', (, ), *, +, coma, -, punto, y /
2. Del 48 al 57 los dígitos del 0 al 9. Por tanto, cualquier dígito se obtiene de la secuencia
binaria 0011 y los 4 bits necesarios para codificar los números del 0 al 9.
3. Del 58 al 64, más signos: dos puntos, punto y coma, <, =, >, ? y @
4. Del 65 al 90 las letras mayúsculas de la A a la Z (no hay Ñ)
5. Del 91 al 96 más signos: [, \, ], ^, _ y `
6. Del 97 al 122 las letras minúsculas de la a a la z (no hay ñ)
7. Del 123 al 126 más signos: {, |, } y ~
3. El 127 es otro carácter de control, el backspace que se corresponde con la tecla de borrado
hacia atrás del teclado.
Por tanto, si hiciésemos una ordenación de varias palabras codificadas mediante ASCII deberíamos
de tener en cuenta que los números los considera menores que las letras (códigos del 48 al 57), y las
mayúsculas (códigos del 65 al 90) menores que las mayúsculas (códigos del 97 al 122), por lo que
si la ordenación es de menor a mayor primero saldrían las palabras que empezasen por números,

-13-

BNext, tu cuenta sin banco.


luego las que empezasen por mayúsculas y luego las que empezasen por minúsculas.
Un problema del código ASCII es que no incluye aquellos símbolos correspondientes a los distintos
alfabetos nacionales. En el caso del español no incluye las Ñ, ñ, ni las vocales acentuadas y con
diéresis, pero en otros lenguajes no incluye otros símbolos.
Por ello, nace el ASCII extendido, cuya idea principal es aprovechar los códigos del 127 al 255 que
no usa el ASCII convencional para representar estos símbolos. Por tanto, en binario, estos códigos
extendidos empiezan siempre por 1.
Surgieron distintas versiones de ASCII extendido en función de los símbolos que se asignasen a
estos códigos que van del 127 al 255. Estas versiones se conocen como code pages o páginas de
código.
Las páginas de código están numeradas, de forma que al computador se le puede especificar (a
través del sistema operativo) que interprete los caracteres según una determinada página de código.
Por ejemplo en un determinado sistema operativo, la página 850 podría incluir la mayoría de
símbolos de los idiomas europeos, pero la 865 podría ser específica de caracteres nórdicos.
Los comités de estandarización internacionales normalizaron estas páginas de códigos, y así la
norma ISO 8859-1 (también conocida como ISO Latin-1) incluye los caracteres propios de los
lenguajes europeos occidentales incluidos el español.
El ISO Latin-1 fue levemente modificada por Microsoft para crear la codificación Windows 1252
que es en la actualidad una de las más extendidas, al ser incorporada por dicho sistema operativo.

2.6.2 Unicode
Unicode es otro estándar de codificación de caracteres que se publica a principios de los 90.
Persigue dar cabida en un mismo código estándar a otras alfabetizaciones además de la latina, como
por ejemplo árabe, hebreo, caracteres asiáticos e incluso ideogramas de algunas cultura indígenas,
de manera que con Unicode es posible tener texto en el que aparezcan caracteres de todos estos
alfabetos. Esto no es posible con los códigos ASCII extendidos, pues cada página de código sólo
cubre algunos alfabetos pero no tantos como Unicode.
Unicode permite representar más de cientos de miles de caracteres de distintos alfabetos. Tiene en
cuenta cuestiones como el orden lexicográfico para hacer ordenaciones de las palabras (evitando
por ejemplo que la ñ quede detrás de la z), visualización de derecha a izquierda, para idiomas como
el árabe o el hebreo que lo requieren, y representación de ideogramas (típicamente para alfabetos
orientales basados en el chino).
En terminología unicode cada carácter se conoce como un code point, el cual tiene un número y
nombre asociado. Los code points se agrupan en planes. Actualmente hay 17 planos, que se
numeran del 00 al 10 (en hexadecimal) y cada uno de ellos tiene 216 (65.536) code points. El plano
00 es el más utilizado y se conoce como BMP o Basic Multilingual Plane, y contiene básicamente
los caracteres de todas las lenguas modernas, por lo que la mayoría de los code points del BMP son
caracteres del chino y otros idiomas basados en el chino (el chino es un lenguaje con miles de
caracteres), pero también da cabida a los alfabetos latinos. Existen, por tanto en la actualidad otros
16 planos (en el futuro podría haber más) que se utilizan para lenguas de la antigüedad, símbolos
matemáticos, símbolos musicales, lenguajes poco comunes etc. y también hay planos reservados
para usos futuros.
Aunque cada carácter tiene asociado ese numerito llamado code point, es posible hacer una
representación comprimida de los code points utilizando lo que se conoce como UTF o Formato de
Transformación de Unicode.

-14-

BNext, tu cuenta sin banco.


En el estándar actual existen 3 UTFs posibles: UTF-8, UTF-16 y UTF-32. Las reglas de cómo
comprimir un code point en un determinado UTF o de cómo descomprimir un código UTF para
obtener el correspondiente code point, están fuera del alcance de estos apuntes, pero debe de quedar
claro que cualquiera que sea el UTF que se use, es capaz de representar todos los code points de
unicode.
UTF-8, como su nombre indica, se basa en intentar codificar la información con 8 bits, pero en
general, los símbolos de UTF-8 pueden ser de longitud variable (de 1 a 4 bytes máximo por cada
carácter).
Tan solo a fin ilustrativo (no es para que te lo estudies) se muestra el criterio con el que UTF-8
utiliza 1, 2, 3 o 4 bytes:
1. Los caracteres de 1 byte son los 128 caracteres ASCII. El byte comienza con un cero:
0XXX XXXX
2. Los caracteres de 2 bytes representan símbolos diacríticos (por ejemplo acentos, diéresis y la
ñ), y alfabetos como el griego, hebreo, y árabe entre otros. El primer byte comienza por 110
y el segundo por 10,:
110X XXXX 10XX XXXX
por lo que no se puede confundir un byte de este tipo con los del grupo anterior que
empezaban siempre por 0.
3. Los de 3 bytes son para alfabetos asiáticos (chino, japones, etc.) siguiendo el formato
1110 XXX 10XX XXXX 10XX XXXX, por lo que tampoco es posible malinterpretar un
byte de un carácter de 3 bytes como uno de un carácter de 1 o 2.
4. Los de 4 bytes son para caracteres de uso poco común, los típicos son los signos
matemáticos, pero también incluye otros alfabetos menos comunes. Siguiendo el mismo
patrón que en los puntos anteriores, tendrían la forma:
1111 0XXX 10XX XXXX 10XX XXXX 10XX XXXX
Por tanto, una ventaja clara de UTF-8 es la compatibilidad que ofrece con ASCII cuando el carácter
es de un solo byte, y que además puede ahorrar espacio de almacenamiento frente UTF-16 y UTF-
32 que requieren respectivamente un mínimo de 16 y 32 bits, sin que por ello se puedan representar
más caracteres que los que se pueden representar con UTF-8.
Sin embargo, UTF-8 es más lento de procesar porque requiere interpretar primero la ristra de ceros
y unos, para ver cuantos bytes corresponden con el carácter que se está leyendo. No obstante, UTF-
8 es el formato de unicode más extendido, y el que se suele usar en páginas web y correos
electrónicos.
UTF-16 también es de longitud variable. Puede utilizar:
1. 2 bytes con los que codifica los caracteres BMP (Plano Multilingüe Básico). Por lo tanto los
caracteres que se usan comúnmente se codifican con longitud fija de 16 bits, esto es de una
forma más sencilla que con UTF-8.
2. 4 bytes con los que codificar los caracteres más extraños (no BMP).
Tan solo a fin ilustrativo (no es para que te lo estudies) se muestra el criterio con el que UTF-16
utiliza 2 o 4 bytes:
Cuando se utilizan 2 bytes sólo estan permitidas combinaciones de 2 bytes que van:
1. Desde 0000 0000 0000 0000 hasta 1101 0111 1111 1111 y
2. Desde 1110 0000 0000 0000 hasta 1111 1111 1111 1111.

-15-

BNext, tu cuenta sin banco.


Esto quiere decir que el resto de combinaciones de 2 bytes
• Desde 1101 1000 000 000 hasta 1101 1111 1111 1111
se usan para hacer combinaciones de 4 bytes. De forma que los 2 primeros bytes están en el rango:
• 1101 1000 000 000 hasta 1101 1010 1111 1111
y los 2 últimos bytes en el rango
• 1101 1011 0000 0000 hasta 1101 1111 1111 1111
Por lo que no es posible que una combinación de 2 bytes tenga grupos de 16 bits que puedan ser
utilizados en combinaciones de 4 bytes, y viceversa.
UTF-32 es el esquema de codificación más sencillo, pues es de longitud fija, y todas las
combinaciones son de 4 bytes. A cambio, tiene un mayor coste de almacenamiento, pues no
comprime los code points.

3 Las operaciones booleanas básicas


El álgebra de Boole define una serie de operaciones a realizar entre datos que sólo pueden tomar
dos valores: Verdadero o Falso. Estas operaciones son fundamentales tanto en el diseño de los
circuitos de los computadores, como a la hora de realizar programas. Por eso conviene introducirlas
en este tema.
Una variable booleana o lógica es aquella que sólo puede tomar dos valores: verdadero o falso (o si
se quiere 1 ó 0). El álgebra de Boole define las siguientes operaciones para variables booleanas:
1. NOT (o negación), esta operación dada una variable la da el valor contrario, como se ve en
la tabla de la verdad para una hipotética variable A:
A NOT A
1 0
0 1
2. OR (u O lógico), esta operación toma 2 variables booleanas, y devuelve verdadero (o 1) si
una de ellas, o las 2 a la vez son verdaderas.
A B A OR B
0 0 0
0 1 1
1 0 1
1 1 1
3. AND (o Y lógico), esta operación toma 2 variables booleanas, y devuelve verdadero (o 1) si
las 2 a la vez son verdaderas.
A B A AND B
0 0 0
0 1 0
1 0 0
1 1 1
4. XOR (u O exclusivo), esta operación toma 2 variables booleanas, y devuelve verdadero (o

-16-
1) si las 2 a la vez son distintas.
A B A XOR B
0 0 0
0 1 1
1 0 1
1 1 0
A XOR B, puede reformularse como (NOT A AND B) OR ( A AND NOT B). Esta propiedad y
otras (como por ejemplo las Leyes de Morgan) las verás en otras asignaturas.
Las operaciones lógicas pueden extenderse para ristras de bits, de manera que se va aplicando
posición a posición, si fuese una operación que requiere dos ristras se aplica entre los 2 bits que
están en la misma posición. Por ejemplo:
• NOT 11001100 = 00110011
• 00110011 OR 10101010 = 10111011
• 00110011 AND 10101010 = 00100010
• 00110011 XOR 10101010 = 10011001
Aunque ahora no te lo parezca estas operaciones tienen gran utilidad.

4 Maquinas de Turing
(Conferencia por el profesor César García Osorio).

5 La Arquitectura de Von Neumann


Los programas de los primeros computadores consistían en una serie de conexiones lógicas entre
distintos componentes del computador. De esta forma, cada vez que se quería que un computador
ejecutase un tipo de tarea distinta, había que volver diseñar cómo cablear todas esas conexiones y
después llevarlo a cabo. Los datos que procesaba el computador, venían dados por otro mecanismo
a parte, como pudieran ser tarjetas perforadas. Por tanto, los programas residían (si se puede decir
así) en una ubicación distinta que los datos.
Lo que propone Von Neumann en 1945 es una arquitectura de computadora en la datos y programas
conviven en un único dispositivo: la memoria del ordenador. Esta idea es fundamental y pervive
intocable hasta los computadores actuales.
Una arquitectura de Von Neumann tiene los siguientes componentes:
1. Dispositivo(s) de entrada/salida
2. La Memoria interna o memoria principal
3. La Unidad Aritmético Lógica o ALU (Arithmetic-Logic Unit)
4. La Unidad de Control
5. Los Buses
La Ilustración 6 muestra un esquema de funcionamiento de la arquitectura Von Neumann, pero para
entenderlo, se hace necesario ver primero cada uno de estos 5 elementos con un poco de
profundidad.

-17-

BNext, tu cuenta sin banco.


5.1 Dispositivo(s) de entrada/salida
Los dispositivos de entrada/salida también se conocen como periféricos. Su función principal es
poner en contacto al computador con el mundo exterior en general, normalmente con un operador
humano.
Los dispositivos de entrada (E en la Ilustración 6), permiten introducir en la memoria del
computador tanto datos (d en la ilustración) como instrucciones ( i en la ilustración),
transformándolas en señales eléctricas equivalentes a 0s y 1s (p.e. ratón, teclado, escáner, lectora de
tarjetas de crédito, … ).
Los dispositivos de salida (S en la ilustración) representan los resultados de los programas
ejecutados por el computador, transformando las señales eléctricas correspondientes a esos 0s y 1s
en señales perceptibles por un usuario (p.e. pantalla, impresora, altavoz), o por otro dispositivo
externo (p.e. el motor de un brazo de un robot, o una válvula de una planta industrial).
Aunque en los tiempos de Von Neumann todavía no existían, dentro de los dispositivos de
entrada/salida, hay algunos muy especiales que se engloban dentro de la deniminación memoria
externa (ME en la ilustración) o dispositivos de almacenamiento masivo. Que son capaces de
almacenar grandes cantidades de información procedente de los resultados de los programas que
ejecuta el computador, pero que también son capaces de almacenar datos y programas que pasarán a
la memoria en el momento de ser ejecutados. Ejemplos de estos dispositivos son los discos duros,
las cintas magnéticas, los pen drives, CDs y DVDs, (aunque estos dos últimos pueden tener
limitado el número de escrituras que soportan).

d,i d
c Salida (S)
Entrada (E) Memoria Externa (ME)

d,i c
c

c Memoria Interna (MI)


Datos e Instrucciones

e e i d

Unidad de Control e c Unidad Aritmético-Lógica


(CU) (ALU)

e e Procesador (CPU)

Unidades Centrales

Ilustración 6: Esquema de la Arquitectura de Von Neumann.

5.2 La Memoria interna o memoria principal


Este componente, aparece como MI en la Ilustración 6. Como se ha dicho, contendrá tanto los datos
como las instrucciones de los programas. Un programa necesita estar cargado en memoria para

-18-

BNext, tu cuenta sin banco.


poder ejecutarse.
La memoria se compone de un conjunto de posiciones o direcciones de memoria, cada una de las
cuales alberga una palabra de memoria. Todas las direcciones tienen palabras con la misma
longitud, que tradicionalmente se mide bytes, pues en la práctica el número de bits de las palabras
de un ordenador es siempre múltiplo de ocho. Por tanto, en una dirección de memoria habrá siempre
una palabra de memoria, la cual o bien no tiene nada relevante (basura), o tiene una instrucción de
un programa, o tiene un dato.
D0
0 1 2 3
4D 65 6D 6F D1
A0
D2
4 5 6 7
A1 72 79 20 49 D3

A2 D4
8 9 10 11
73 20 05 33 D5
A3
12 13 14 15 D6
65 12 A1 B3 D7

w/r
Ilustración 7: Esquema de funcionamiento de la memoria interna.

Gracias a que no hay dos direcciones de memoria iguales en un computador, es posible leer o
escribir el contenido (la palabra) de una dirección de memoria determinada especificando el valor
de la dirección de memoria a la que se quiere acceder.
En la Ilustración 7 vemos como se podría producir estas dos operaciones en una memoria de
ejemplo con 16 posiciones o direcciones, numeradas del 0 al 15 (están numeradas en decimal, ver
las esquinitas de cada celda). El contenido de cada dirección de memoria se ha representado en
hexadecimal. Así en la dirección 8 vemos que el contenido es 73.
Dos dígitos hexadecimales en binario ocupan 8 bits, por lo que vemos que todas las direcciones
contienen almacenados 8 bits. Esos 8 bits de cada celda, son por lo tanto las palabras de memoria, y
8 bits (o 1 bytes) es la longitud de las palabras de memoria, que se puede observar que es siempre 8
en todas las direcciones, pues incluso en la celda 10, aunque contiene un 5=0101, relamente lo que
contiene es un 05=0000 0101 que efectivamente ocupa 8 bits.

5.2.1 La Operación de Lectura


Cuando se quiere producir una lectura, por las conexiones numeradas como A0..A3, llega la
dirección en binario de la palabra que se quiere leer. Así, si por ejemplo, queremos leer el contenido
de la dirección 12, tendremos:
A3.= 1 A2.= 1 A1.= 0 A0.= 0
ya que 1100 es 12 en binario. Como queremos leer la conexión w/r que indica si queremos hacer
una escritura (w de write) o una lectura (r de read) tomara el valor correspondiente a la r, que
supongamos que es 0. El momento exacto de cuando hacer esa lectura vendrá indicado por el
siguiente momento en el que la conexión con la onda cuadrada (que se llama señal de reloj)
ascienda a su nivel superior.

-19-

BNext, tu cuenta sin banco.


Tras hacer esa lectura los datos leídos se depositarían en las conexiones D0..D7 que al leer la
posición 12 obtendrían un 65 (hexadecimal), es decir 0110 0101:
D7.= 0 D6.= 1 D5.= 1 D4.= 0 D3.= 0 D2.= 1 D1.= 0 D0.= 1

5.2.2 La Operación de Escritura


La operación de escritura transcurriría así. Supongamos que se quiere escribir A3 en la dirección 13.
Entonces, como en el caso anterior, a las conexiones A0..A1, llega la dirección de la celda donde se
va a escribir:
A3.= 1 A2.= 1 A1.= 0 A0.= 1
A las conexiones D0..D7 llega el dato a escrbir: A3 = 1001 0011, por lo que:
D7.= 1 D6.= 0 D5.= 0 D4.= 1 D3.= 0 D2.= 0 D1.= 1 D0.= 1
En la conexión w/r ahora activaremos la w (de write), que siendo consistentes con el ejemplo
anterior, debiera de tener un 1. E igual que en el caso de la lectura, el instante preciso en que se
escribe vendrá dado por el momento en que suba la señal de reloj.

5.2.3 Tipos de memorias


Aunque en otras asignaturas verás clasificaciones más exhaustivas de la memoria, la más conocida
es la siguiente:
• RAM (Random Access Memory) Es la parte de la memoria principal en la que tanto se puede
leer, como escribir. Su contenido es volátil, pues se pierde al apagar el computador.
• ROM (Read Only Memory) Es la parte de la memoria principal que sólo se puede leer, y
cuyo contenido no se pierde al apagar el ordenador (es persistente: lo contrario de volátil).
LA ROM contiene algunos datos y programas muy importantes, que son provistos por el
fabricante, y que es necesario que estén siempre presentes en el computador.
La memoria interna es más rápida que la externa, pero suele tener menos capacidad que la externa.
La memoria externa es siempre persistente, mientras que la RAM no lo es y la ROM sí lo es.

5.2.4 Medidas de Capacidad de la memoria


Como ya hemos visto 1 byte son 8 bits. Normalmente los dispositivos de memoria, tanto principal
como externa tienen capacidades mucho mayores, son capaces de almacenar mucha más
información. Por ello, la capacidad en estos casos se mide en unidades mayores, las cuales
combinan los prefijos Kilo/Mega/Giga/Tera con los sufijos bits/bytes/palabras.
Los prefijos Kilo, Mega, Giga y Tera, normalmente se indican por su primera mayúscula (K, M, G y
T respectivamente).
Estos prefijos indican siempre una potencia de 2 elevado a un múltiplo de 10. Así Kilo indica 210,
Mega indica 220, Giga indica 230, y Tera 240. Debido a que 210 = 1024, podemos asumir que Kilo
indica aproximadamente mil, Mega indica aproximadamente un millón, Giga indica
aproximadamente mil millones, y Tera indica un billón.
Por tanto, teniendo en cuenta que 1 byte = 23 bits, las siguientes equivalencias son ciertas:

-20-
Bits Bytes
10 7
1 KBit 2 bits 2 bytes

1 MBit 220 bits 217 bytes

1 GBit 230 bits 227 bytes

1 TBit 240 bits 237 bytes

1 Kbyte = 1 Kb 213 bits 210 bytes

1 Mbyte = 1 Mb 223 bits 220 bytes

1 Gbyte = 1 Gb 233 bits 230 bytes

1 Tbyte = 1 Tb 243 bits 240 bytes

Tabla 6: Equivalencia entre unidades de bits y bytes.


Las unidades de bits: Kilobits, Gigabits etc. se usan más para especificar anchos de banda en
canales de comunicación (por ejemplo, x Kilobits/sg), que para especificar cantidades de memoria.
Normalmente la capacidad de un dispositivo de memoria externa o interna se especifica por número
de bytes. En el caso de las memorias internas también cabe especificar el número de palabras
(words) de memoria. Por tanto, existen las unidades Kilopalabra o Kword, Megapalabra,
Gigapalabra y Terapalabra. En este caso tendremos en cuenta que el número de bits o bytes de una
palabra de memoria no es fijo, sino que depende de cada máquina.
En la tabla se muestran las equivalencias para longitudes de palabra de 1 byte, 2 bytes, 4 bytes y 8
bytes.
1 palabra = 1 byte 1 palabra = 2 bytes 1 palabra = 4 bytes 1 palabra = 8 bytes
1 KBit 27 palabras 26 palabras 25 palabras 24 palabras

1 MBit 217 palabras 216 palabras 215 palabras 214 palabras

1 GBit 227 palabras 226 palabras 225 palabras 224 palabras

1 TBit 237 palabras 236 palabras 235 palabras 234 palabras

1 Kbyte 210 palabras 29 palabras 28 palabras 27 palabras

1 Mbyte 220 palabras 219 palabras 218 palabras 217 palabras

1 Gbyte 230 palabras 229 palabras 228 palabras 227 palabras

1 Tbyte 240 palabras 239 palabras 238 palabras 237 palabras

Tabla 7: Equivalencia bits/bytes con distintas longitudes de palabra de memoria.


En las secciones que han detallado las operaciones de lectura y escritura en memoria, se ha visto
como para las 16 posiciones de memoria de la Ilustración 7 han sido necesarias 4 conexiones A0..A3
para poder hacer referencia a cada posición de memoria. Esto es debido a que con 4 dígitos binarios
se pueden hacer 24 combinaciones, esto es 16.

-21-

BNext, tu cuenta sin banco.


En general, cada posición de memoria tiene una palabra completa, luego si la memoria tiene n
posiciones necesitaremos como mínimo m conexiones o dígitos binarios para poder hacer referencia
a todas esas posiciones, de manera que:

2m ≥ n
Por lo que tomando logaritmos en ambos lados de la inecuación:

m ≥ lg2 n
Por tanto, para direccionar n palabras, necesitamos que las direcciones de memoria sean al menos
de longitud lg2 n bits. En la siguiente tabla se ven algunos ejemplos de longitud de dirección
mínima para algunas capacidades medidas en longitud de palabra.
Capacidad de la memoria en palabras Longitud mínima de las direcciones de
memoria en número de bits
1 Kpalabra 10 bits
1 Megapalabra 20 bits
1 Gigapalabra 30 bits
1 Terapalabra 40 bits
Tabla 8: Longitud mínima de las direcciones de memoria para distintos tamaños de la misma.
En la actualidad, los ordenadores personales están haciendo al transicción entre 32 y 64 bits para
direccionamiento. Esto significa que los ordenadores de 32 bits sólo podían direccionar a lo
máximo 2 Gigapalabras, mientras que los de 64, podría direcciónar 224 Terapalabras (24+40=64).

5.3 La Unidad Aritmético Lógica o ALU (Arithmetic-Logic Unit)


Es un circuito que se encarga de dados unos datos (operandos) hacer con ellos una operación dada
y devolver un resultado. La operación en cuestión depende de lo que se le pida a la ALU en ese
momento, pero, como su nombre indica, pueden ser operaciones de tipo arítméticos (p.e. sumas,
restas, divisiones, y multiplicaciones ), y lógicas (p.e. comparar dos datos para ver si son iguales, si
uno es mayor que otro, hacer operaciones de tipo booleano).
Operando Operando
1 2
(8 bits) (8 bits)

Operación
ALU

Resultado
(8 bits)
Ilustración 8: Ejemplo de Unidad Aritmético-Lógica.

Supongamos una ALU muy simple como la de la ilustración. La llegan 2 operandos de 8 bits, a
traves de sendos grupos de 8 conexiones, y devuelve un resultado a través de otro grupos de 8
conexiones. Se supone, que en este caso, la longitud de palabra de memoria también será 8, pues los
operandos podrían haberse leído de memoria, y a su vez el resultado podría escribisrse en memoria;
por lo que se hace necesario que los tamaños de palabra de memoria, operandos y resultado
coincidan.
Para indicarle a la ALU qué operación ha de realizar habrá una seria de conexiones, como por

-22-

BNext, tu cuenta sin banco.


ejemplo las 2 que aparecen a la izquierda indicando qué operación en concreto. Por ejemplo, con 2
conexiones es posible hacer cuatro combinaciones binarias, que podrían corresponderse con 4
operaciones. Por ejemplo: 00 que sea sumar, 01 que sea restar, 10 que sea AND y 11 que sea OR.
Lógicamente el repertorio de operaciones que puede realizar una ALU de verdad es mucho más
amplio, por lo que las conexiones que indican que operación a realizar serán mas numerosas.
A la derecha de la ALU nuevamente vemos una señal de reloj, que como en el caso de la memoria
interna, marcará en qué momento concreto se realizará la operación.

5.4 La Unidad de Control


Se encarga de leer de la memoria cada instrucción del programa (típicamente la siguiente), la
interpreta, y una vez “entiende” su significado, manda señales de control al resto de partes del
computador para ejecutarlas.
Para ello, la unidad de control contiene un pequeño conjunto de posiciones de memoria especiales
que se conocen como registros. Los registros se utilizan para almacenar operandos leídos de
memoria antes de dárselo a la ALU, y también los resultados que se obtienen de las operaciones
realizadas por la ALU antes de escribirlos en la RAM.
Uno de los registros se llama contador de programa. El contador de programa lleva la cuenta de la
instrucción del programa en ejecución que se está ejecutando en ese momento. Concretamente lo
que guarda el contador de programa es la dirección de memoria de dicha instrucción.
Por lo tanto, antes de interpretar lo que hace una instrucción de programa, la unidad de control tiene
que hacer los siguientes pasos:
1. Incrementar el contador de programa en una unidad, con lo cual ahora contiene la dirección
de memoria siguiente a la de la instrucción actual.
2. Leer de memoria el contenido de la dirección indicada por el contador de programa. La
palabra de memoria leída contendrá la siguiente instrucción a ejecutar.
Una vez la unidad de control ha leído la siguiente instrucción tiene que interpretarla. Puede haber
típicamente instrucciones sin operandos, con un solo operando, o con dos. Cualquiera que sea el
tipo de instrucción, todas son un conjunto de bits, típicamente una palabra de memoria. Una parte
de esos bits, indican de qué operación se trata, y se conoce como código de operación, el resto de
bits de la instrucción codifican los operandos.
Por ejemplo, supongamos una máquina con palabras de memoria de 16 bits, y que esa misma
longitud es la de las instrucciones. Supongamos una instrucción de dos operandos. Podría ser de la
forma:
Código de Operación Operando 1 Operando 2
0 1 1 0 0 0 0 0 1 1 0 0 0 0 1 0

Donde por ejemplo los 4 primeros bits son el código de operación, los 6 siguientes representan al
primer operando y los 6 siguientes al segundo. Por ejemplo, supongamos que se trata de la
operación suma y que está codificada con el código de operación 0110. La unidad de control conoce
que lo que le pide la instrucción es una suma y no es una resta, porque la resta tendrá otro código de
operación distinto. Al recibir ese código de operación la unidad de control sabrá que tiene que leer
esos operandos (quizás de unos registros, aunque existen más posibilidades que ahora no vamos a
detallar), y depositar el resultado quizás en la posición del segundo operando.
En este caso el operando 1 podría saber que está en un registro porque esa máquina entiende que

-23-

BNext, tu cuenta sin banco.


cuando los 3 primeros bits de ese operando son cero, es así, y además los 3 siguientes indican qué
registro en concreto1. Por tanto el primer operando está en el registro 011 (el 3) y el segundo en el
010 (el 2). Además la operación suma está definida en este ejemplo, de manera que el resultado
vaya a parar al segundo operando, por tanto al registro 2.
El cómo han llegado los operandos desde memoria a los registros, y cómo a su vez, el resultado en
el registro 2 se puede volver a escribir en memoria, es una cuestión más compleja que ya verás en
otras asignaturas, pero sería utilizando una instrucción mover también de 2 operandos, en la que un
operando es lo que quiero mover (por ejemplo el resultado en el registro 2) y el otro la posición
destino del movimiento (por ejemplo una dirección de memoria). La instrucción mover tendría, a su
vez otro código de operación distinto.
La frecuencia del reloj se mide en Mhz o en Ghz, y su periodo se conoce como tiempo de ciclo.
Cada instrucción puede requerir (tardar) un número de ciclos distintos, dependiendo de lo compleja
que sea. Siguiendo con el ejemplo de la suma, una vez conocidos donde están los operandos, serán
suministrados a la ALU (paso 1), se la dará la orden a la ALU de que haga la suma (paso 2) y se
recogerá el resultado para llevarlo al registro correspondiente (paso 3), el registro 2 en el ejemplo.
Todo esto, requiere 3 pasos secuenciados uno detrás de otro, de manera que uno no comience hasta
que haya acabado el anterior. Por eso es necesaria la señal de reloj. A pulso de la señal de reloj se
irán realizando uno de estos pasos. Por tanto cada instrucción se compone de varios pasos/pulsos de
reloj, empezando por el paso que incrementa el contador de programa, el que lee de memoria la
siguiente instrucción y el que la decodifica. Estos 3 pasos serían comunes a cualquier instrucción,
pero.
Es común encontrarse con los, por ejemplo gigahercios, de una unidad de control como medida de
su velocidad, si bien existen otras medidas como por ejemplo: MIPS millones de instrucciones
ejecutadas por segundo, y los FLOPS Floating point- Operations per Second, número de
operaciones en coma flotante por segundo. Estas última medida es más propia de máquinas
dedicadas a cálculos masivos.
Los programas hechos a base de instrucciones en binario como las descritas, se conocen como
programas en código máquina. En la actualidad nadie o casi nadie programa ya en código
máquina, y caso de hacerlo utilizarían lo que se conoce como un lenguaje ensamblador. El
ensamblador permite codificar cada instrucción de código máquina a través de un código
mnemónico que es más sencillo de recordar y teclear para el programador. Por ejemplo, la anterior
instrucción de suma del contenido de los registros 3 y 2 podría ser “ADD R3, R2” en un
determinado ensamblador, lo cual es mucho más inteligible para un humano que 011000011000010.
Programar en código máquina o en ensamblador permite el máximo nivel de optimización del
programa, para que vaya más rápido, pero exige por un lado conocimientos avanzados de nuestra
unidad de control, y además hacer programas más largos que en otros lenguajes de programación
más avanzados (debido a que cada instrucción en un lenguaje de programación moderno está
compuesta por varias instrucciones en código máquina).
Además cuando cambiáramos de unidad de control, ese programa en código máquina ya no
funcionaría, mientras que en los lenguajes de programación modernos tendremos herramientas para
traducir el programa al lenguaje máquina de la unidad de control deseada (i.e. compiladores e
intérpretes).
Si nos fijamos en la Ilustración 6, de la unidad de control parten conexiones etiquetadas como c y
llegan conexiones etiquetadas como e. Las conexiones etiquetadas como c son las señales de
control que manda la unidad de control al resto de unidades, entre ellas se encuentra la señal de
reloj, pero habría más, como por ejemplo las que indican qué operación hacer a la ALU. Las señales

1 El ejemplo está inspirado en el lenguaje máquina del procesador PDP-11 de DEC.

-24-
etiquetadas como e son las señales de estado siguen el camino inverso y sirven de indicadores a la
unidad de control de que las operaciones realizadas han dado o no algún problema, situación o
circunstancia especial. Por ejemplo, la ALU debería de indicar de alguna forma a la unidad de
control que una operación ha dado lugar a un resultado con más dígitos de los permitidos (i.e. un
desbordamiento u overflow).
La unidad de control también manda señales de control y recibe señales de estado de los periféricos.
Normalmente es la unidad de control la que a través de señales de control ordena hacer operaciones
a los periféricos, pero puede darse el caso de que sea el periférico el que solicite la atención de la
unidad de control, mandándole una señal. Estas señales de los periféricos hacia la unidad de control
se conocen como interrupciones. El nombre viene de que la unidad de control tiene que dejar de
realizar el programa en curso, para atender la petición del correspondiente periférico. Por ejemplo,
un periférico puede decir a la unidad de control “dame más datos de memoria que ya he acabado de
imprimir o de grabar los que me mandaste antes”.
La unidad de control y la ALU forman la CPU2 (Central Process Unit) y en los computadores
modernos vienen juntas en un único componente, que es el microprocesador.

5.5 Buses
Son conexiones que transmiten información sobre instrucciones, datos y direcciones de memoria
entre las distintas unidades del computador. En la Ilustración 6 se corresponden con las conexiones
etiquetadas con d e i (datos e instrucciones).
Una de las formas que hay de clasificar la transmisión digital de la información es distinguir entre
comunicaciones en serie y en paralelo. En las comunicaciones en serie la información se transmite
de manera que en cada instante el emisor sólo envía al receptor un bit; mientras que en la
comunicación en paralelo existen n conexiones entre el emisor y el receptor, lo que permite enviar
la información de n en n bits. Los buses utilizan la comunicación en paralelo, el número de bits que
puede trasmitir simultáneamente un bus se conoce como anchura del bus.

5.6 Problemas del Modelo Von Neumann

5.6.1 Cuello de botella entre memoria y unidad central


Una primera impresión que se puede obtener a la vista de este modelo es que la forma de mejorar el
rendimiento de un computador es aumentar la velocidad de trabajo de la unidad de control,
típicamente aumentando la frecuencia de su reloj en la medida de lo que permita la tecnología del
momento.
No obstante, en la mayoría de las computadoras la velocidad de transmisión entre memoria y la
unidad de control es menor que la velocidad de procesamiento de la propia unidad de control, por lo
que en un proceso que requiriese muchas transferencias de memoria, cosa que por otro lado es
habitual, se notarían muy poco las mejoras sobre la unidad de control. Este problema, que se conoce
como cuello de botella de Von Neumann.
La solución más común a este problema consiste en incluir en la unidad central una especie de
memoria RAM de menor capacidad que la memoria RAM propiamente dicha, esta memoria se
conoce como memoria caché.
La memoria caché es muy rápida, e idealmente debiera de almacenar los datos de memoria interna

2 En un abuso del lenguaje actualmente el término CPU también es usado de forma incorrecta para designar la carcasa
de un PC junto con todo lo que contiene. Esta denominación errónea no debe de confundirnos.

-25-

BNext, tu cuenta sin banco.


más utilizados por el programa que se esté ejecutando en ese momento, de forma que una vez hayan
sido traídos desde la memoria interna a la caché, cada vez que haya que volver leerlos o
modificarlos, se hará en la caché, tardando menos que si esas operaciones se hicieran sobre la
unidad interna.

5.6.2 Cuellos de botella por periféricos


Las transmisiones de información entre los periféricos y la memoria son problemáticas, en tanto la
velocidad de los periféricos es muy inferior y ralentiza el funcionamiento del sistema. Algunos
períféricos, como por ejemplo los dispositivos de almacenamiento masivo, están recibiendo y
enviando información constantemente a la memoria, por lo que se necesita que esa comunicación
sea fluida.
La Ilustración 9 muestra lo que podría ser el punto de partida del problema. La comunicación entre
la memoria y la CPU tiene un bus separado al bus que realiza la comunicación entre periféricos y
CPU. El problema es que toda la comunicación entre periféricos y memoria ha de hacerse a través
de la CPU, utilizando sus registros como punto de paso intermedio. Como hemos visto en la sección
anterior, la propia memoria interna no es tan rápida como la CPU, pero los periféricos son aún mas
lentos, haciendo que la CPU quede parada en esos momentos en los que la información circula entre
memoria y periféricos.
Una mejora es utilizar una arquitectura unibús llamado bus del sistema, en la que hay un único bus
que comparten periféricos y memoria (ver Ilustración 10).

Memoria

CPU Periférico 0 Periférico 1

Ilustración 9: Interconexión de la UC utilizando un bus separado para memoria y otro para los
periféricos.

CPU Memoria Periférico 0 Periférico 1

Ilustración 10: Modelo UNIBUS.

Aparentemente, el problema parece resuelto, pues los datos pueden circular entre memoria y
periféricos, sin que tengan que pasar entre medias por la CPU. Sin embargo, en el modelo unibús la
CPU es la encargada de controlar el tráfico por el bus. Si se necesita una transferencia de datos en la
que intervenga un periférico o la memoria, la CPU deberá de indicar al bus cual es el origen y
destino de la comunicación, prohibiendo al resto de elementos conectados al bus, que lo utilicen en
esos momentos.
La lentitud de los periféricos, puede hacer que el tiempo en el que el bus quede bloqueado sea

-26-

BNext, tu cuenta sin banco.


demasiado largo. Para reducir ese problema la solución inmediata es incorporar en cada periférico
una memoria intermedia o buffer, de forma que el bus del sistema ahora sólo transfiere datos entre
la memoria interna y el buffer. El buffer al ser una especie de RAM tendrá una velocidad parecida a
la memoria interna, y los tiempos en los que el bus queda bloqueado serán más breves. En el lado
del periférico, éste irá consumiendo a su ritmo el contenido del buffer si por ejemplo es un
periférico de salida como una impresora o un disco, o irá escribiendo en el mismo si es de entrada
como un teclado o un disco (los discos pueden hacer los 2 papeles).
Otras posibilidades, no excluyentes a la utilización de buffer, y que también ayudan a mejorar la
fluidez de la comunicación entre y con los periféricos, son la utilización de controladores E/S y
controladores DMA.
Los controladores E/S también se conocen como canales. Consiste en un procesador con un amplio
buffer, especializado en controlar las operaciones de transferencia entre los periféricos conectados a
él (que pueden ser varios) y el resto de periféricos junto con el procesador.
La Ilustración 11 muestra una arquitectura de este tipo, en la que se puede ver que los periféricos
etiquetados con 0 seguido de otro dígito están asociados al controlador 0, mientras que los
periféricos etiquetados con 1 seguido de otro dígito están asociados al otro controlador. Las
transferencias entre periféricos del mismo controlador son directas, y no necesitan de ninguna
espera por parte del resto del sistema que puede seguir haciendo el resto de tareas en paralelo.
Un ejemplo típico sería un controladora de disco a la que fuesen conectados varios dispositivos de
almacenamiento masivo.

CPU Per. 00 Per. 01 Per. 0n Per. 10 Per. 11 Per. 1n

Caché Memoria Controlador E/S Controlador E/S

Canal 0 Canal 1

Bus del Sistema


Ilustración 11: Arquitectura con controladoras E/S.

La forma de trabajo con contralores se puede resumir en los siguientes pasos:


1. La CPU inicia la operación y para ello se pone en contacto con el controlador indicándole:
1. El tipo de operación (si es lectura o escritura)
2. Los periféricos involucrados
3. El tamaño del bloque de datos. Esto es, los datos no se transfieren bit a bit, sino por
bloques que irán a/desde la caché de la CPU desde/a un buffer. No parece interesante
bloquear el bus del sistema impidiendo al resto de dispositivos usarlo, para transmitir un
solo bit, sino que cada vez que se bloquee se aprovecha para transmitir varios que
componen ese bloque.
El tamaño del bloque no puede ser mayor que el del buffer que va a enviar o recibir la
información. Por tanto, a mayor tamaño del buffer se pueden transmitir bloques más
grandes mejorando el rendimiento del sistema.
2. Cuando el periférico finaliza la operación, manda una interrupción a la CPU diciendo que

-27-

BNext, tu cuenta sin banco.


los periféricos están listos para realizar otra operación.
Como se ve en la Ilustración 11 el bus del sistema sigue siendo el mismo para las transferencias
entre memoria y CPU que para las transferencias de/entre los periféricos; por lo que sigue
existiendo el problema de que unas tienen que esperar a otras. La solución podría ser añadir un bus
dedicado a los periféricos, distinto a l bus de memoria (ver Ilustración 12). En cierta forma,
volvemos a la situación de la Ilustración 9, pero incorporando buffers y controladoras.
Con los buffers se ha evitado que el procesador tenga que adaptarse a la velocidad de los
periféricos. Con las controladoras, tenemos esos buffers y además aislamos el tráfico entre
periféricos de la misma controladora; y finalmente incorporando un bus dedicado a los periféricos,
hacemos que las transferencias entre la CPU y la memoria no tengan que competir por el mismo bus
que las transferencias en las que intervienen los periféricos.

Per. 00 Per. 01 Per. 0n Per. 10 Per. 11 Per. 1n

Controlador E/S Controlador E/S

CPU Canal 0 Canal 1

Bus E/S
Caché Memoria Adaptador Bus

Bus del Sistema

Ilustración 12: Arquitectura con controladoras E/S y bus dedicado de E/S.

Sin embargo, a pesar de todas estas mejoras, cuando hay un intercambio de información entre la
memoria y un periférico, nos sigue pasando lo mismo que la arquitectura inicial de la Ilustración 9:
la información en ese caso en algún momento tiene que pasar por la CPU, ocupando registros y
tiempo de CPU.
Para resolver este problema aparecen los controladores DMA (Direct Memory Access) o
controladores de acceso directo a memoria, que se trata de un procesador especializado que
permite la transferencia directa de datos memoria-periférico.

-28-
Per. 00 Per. 01 Per. 0n Per. 10 Per. 11 Per. 1n

Controlador E/S Controlador E/S

CPU Canal 0 Canal 1

Bus E/S
Caché DMA Memoria

Bus del Sistema

Ilustración 13: Arquitectura con controladoras E/S, bus dedicado de E/S y dispositivo DMA.

Una operación de E/S que involucrara a la memoria y a un periférico, ahora con DMA sería de la
siguiente forma:
1. La CPU inicia la operación transmitiendo la siguiente información a la controladora DMA:
1. Tamaño del bloque de datos
2. Dirección en la que se encuentran los datos en la unidad origen
3. Dirección en la que se encuentran los datos en la unidad destino
4. Sentido de la transferencia (lectura o escritura)
2. A partir de ese momento la CPU cede el control del bus del sistema al controlador DMA, y
se dedica a otras tareas.
3. Cuando finaliza la transferencia:
1. El controlador DMA manda una interrupción a la CPU indicando que ya ha acabado.
2. La CPU vuelve a hacerse con el control de bus del sistema.

6 Clasificación de los Computadores


Atendiendo a su tamaño y rendimiento es común encontrarse con las siguientes denominaciones
para según que máquinas:
Un supercomputador es una máquina capaz de realizar un número muy elevado de operaciones de
cálculo, normalmente para fines científicos o ingenieriles. Para poder realizar esta tarea puede tener
cientos de CPUs que trabajan en paralelo de forma coordinada.
Una forma relativamente asequible de tener un supercomputador es mediante un clúster, que es un
conjunto de computadoras con elementos comunes, que se comportan como si fuesen una sola.
Un mainframe es un término que suele aplicarse a una gran computadora que procesa grandes
cantidades de datos, soportando el acceso concurrente de gran cantidad de usuarios. Estas
computadoras suelen estar en una sala refirgerada funcionado de manera ininterrumpida soportando
aplicaciones críticas con una alta demanda de recursos de procesador y almacenamiento. Debido a
su alto coste, se crearon sistemas similares más baratos y de menores prestaciones, que son los
llamados minicomputadores o minis.

-29-

BNext, tu cuenta sin banco.


Los computadores personales o PCs, en principio fueron máquinas de sobremes pensadas para
que las utilizase un sólo usuario en aplicaciones de tipo doméstico, y por tanto son por definición
más baratas que otros tipos de máquinas vistas como las vistas anteriormente.
Con el tiempo los PCs mejoraron sus prestaciones, soportando múltiples usuarios, aumentando su
capacidad de cálculo y almacenamiento, y reduciendo todavía más su coste. De esta evolución salen
las estaciones de trabajo o workstations que siendo máquinas de sobremesa se caracterizan por su
potencia a nivel de cálculo y gráficos, y que se utilizan mucho en ingeniería y en ámbitos
científicos.
Otra evolución de los PCs son los ordenadores portátiles y en la actualidad los teléfonos
inteligentes.

-30-

BNext, tu cuenta sin banco.

Das könnte Ihnen auch gefallen