<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>El Cedazo &#187; Electrónica</title>
	<atom:link href="https://eltamiz.com/elcedazo/category/electronica/feed/" rel="self" type="application/rss+xml" />
	<link>https://eltamiz.com/elcedazo</link>
	<description>Comparte conocimiento.</description>
	<lastBuildDate>Sun, 01 Feb 2026 06:35:56 +0000</lastBuildDate>
	<language>es-ES</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
		<item>
		<title>Computador mágico XXXII &#8211; Epílogo</title>
		<link>https://eltamiz.com/elcedazo/2014/09/15/computador-magico-xxxii-epilogo/</link>
		<comments>https://eltamiz.com/elcedazo/2014/09/15/computador-magico-xxxii-epilogo/#comments</comments>
		<pubDate>Mon, 15 Sep 2014 08:05:15 +0000</pubDate>
		<dc:creator>J</dc:creator>
				<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[J]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=20746</guid>
		<description><![CDATA[La serie &#8220;El computador mágico&#8221; está disponible también en forma de libro. A lo largo de esta serie hemos visto cómo funciona un ordenador, empezando por sus componentes más básicos, los transistores, y subiendo cada vez más en abstracción hasta llegar al sistema operativo y los programas de usuario. He intentado cubrir todo el camino completo, [...]]]></description>
			<content:encoded><![CDATA[<div align="left">
<table class="bookBox" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<td valign="center">
<p style="text-align: center; margin-top: 1px; margin-bottom: 1px; margin-left: 1px;" align="center"><a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liimagelink"><img class="aligncenter size-full wp-image-18513" title="Computador mágico" src="http://eltamiz.com/elcedazo/wp-content/uploads/2016/01/ComputadorMagicoDigest_v21_cover_v1_front2.png" alt="" width="90" height="128" /></a></p>
</td>
<td valign="center">

<p style="text-align: left;" align="center">
La serie &#8220;El computador mágico&#8221; está disponible también <a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liinternal">en forma de libro</a>.
</p>
</td>
</tr>
</tbody>
</table>
</div>

<p>A lo largo de esta <a href="/elcedazo/series/computador-magico/" title="Computador mágico" target="_blank" class="liinternal">serie</a> hemos visto cómo funciona un ordenador, empezando por sus componentes más básicos, los transistores, y subiendo cada vez más en abstracción hasta llegar al sistema operativo y los programas de usuario.</p>

<p>He intentado cubrir todo el camino completo, pero sin entrar en demasiado detalle en ninguno de los artículos (si alguien quiere más detalle de algo concreto, que lo pida y veremos qué se puede hacer), pero permitiendo seguirlo a alguien sin conocimientos previos (espero&#8230; esa era al menos la intención).</p>

<p>No obstante, por si alguien quiere profundizar, vamos a dejar algunas referencias a textos más profundos. No conozco ningún texto que cubra todo el camino en profundidad, porque cada una de las áreas que cubre esta serie es complicada en sí misma, así que tendré que dar varias referencias.</p>

<p>Para la parte inicial es útil algún libro de electrónica. Yo he utilizado (tanto para esta serie como cuando lo estudié hace ya unos añitos) el libro &#8220;Microelectrónica&#8221; de Jacob Millman y Arvin Granbel. Cubre más o menos desde el principio hasta la lógica secuencial.</p>

<p>Para la parte media, el mejor libro que conozco es &#8220;Curso de ordenadores: conceptos básicos de arquitectura y sistemas operativos&#8221;, de Gregorio Fernández. Tanto es así que los ordenadores C16 que hemos visto aquí se basan en lo que Gregorio usa en su libro.</p>

<p>Para la parte final, la de sistemas operativos, es muy interesante el libro &#8221;Operating System Concepts&#8221; de A. Silberschatz y P. Galvin. Otro muy bueno es &#8221;Operating systems: design and implementation&#8221; de Andrew S. Tanenbaum; probablemente no es el mejor, pero Andrew escribe muy bien, y además te da su propio sistema operativo, Minix, para que vayas viendo en el código lo que te cuenta en la parte teórica.</p>

<p>Fue un placer.</p>

<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2014/09/15/computador-magico-xxxii-epilogo/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<item>
		<title>Computador mágico XXXI &#8211; Arranque hasta el buscaminas</title>
		<link>https://eltamiz.com/elcedazo/2014/08/02/computador-magico-xxxi-arranque-hasta-el-buscaminas/</link>
		<comments>https://eltamiz.com/elcedazo/2014/08/02/computador-magico-xxxi-arranque-hasta-el-buscaminas/#comments</comments>
		<pubDate>Sat, 02 Aug 2014 08:11:57 +0000</pubDate>
		<dc:creator>J</dc:creator>
				<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[J]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=20735</guid>
		<description><![CDATA[La serie &#8220;El computador mágico&#8221; está disponible también en forma de libro. Ya hemos visto a lo largo de la serie cómo funciona el hardware de un ordenador, hemos visto más o menos qué hace un sistema operativo y cómo lo hace&#8230; solo nos queda ver cómo empieza el mundo: yo le doy al botón de [...]]]></description>
			<content:encoded><![CDATA[<div align="left">
<table class="bookBox" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<td valign="center">
<p style="text-align: center; margin-top: 1px; margin-bottom: 1px; margin-left: 1px;" align="center"><a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liimagelink"><img class="aligncenter size-full wp-image-18513" title="Computador mágico" src="http://eltamiz.com/elcedazo/wp-content/uploads/2016/01/ComputadorMagicoDigest_v21_cover_v1_front2.png" alt="" width="90" height="128" /></a></p>
</td>
<td valign="center">

<p style="text-align: left;" align="center">
La serie &#8220;El computador mágico&#8221; está disponible también <a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liinternal">en forma de libro</a>.
</p>
</td>
</tr>
</tbody>
</table>
</div>

<p>Ya hemos visto a lo largo de la <a href="http://eltamiz.com/elcedazo/series/computador-magico/" target="_blank" class="liinternal">serie</a> cómo funciona el hardware de un ordenador, hemos visto más o menos qué hace <a href="http://eltamiz.com/elcedazo/2014/06/22/computador-magico-xxx-sistema-operativo-ii-funcionamiento/" target="_blank" class="liinternal">un sistema operativo</a> y cómo lo hace&#8230; solo nos queda ver cómo empieza el mundo: yo le doy al botón de encendido en el ordenador y entonces ¿qué ocurre?</p>

<p>El problema de explicar esto es que, aunque hay cosas comunes, cada ordenador y cada sistema operativo es diferente. Así que vamos a centrarnos en los sistemas que más utilizamos en casa: los PCs con MS Windows.</p>

<p>Todo empieza cuando el usuario le da al botón de encendido. Todos los microchips del ordenador reciben alimentación y empiezan a funcionar. En particular, la CPU empieza con su ciclo: mira la dirección de memoria a donde apunta PC (recordad: el <em>Program Counter</em>) y ejecuta lo que haya ahí&#8230; así una y otra vez.</p>

<p>Así que, como acaba de empezar, lo que hará es ejecutar lo que haya en la posición 0&#215;00000000. ¿Qué hay ahí? En los ejemplos que hemos visto hasta ahora lo que había ahí era nuestro programa, pero claro, ahora queremos algo más versátil, un PC de escritorio normal y corriente, así que no podemos esperar que ahí esté precisamente el programa que quiere ejecutar el usuario.</p>

<p>Lo que hay ahí es la BIOS.</p>

<p>BIOS significa <em>Basic Input-Output System</em> (sistema de entrada-salida básico)<sup>[<a href="https://eltamiz.com/elcedazo/2014/08/02/computador-magico-xxxi-arranque-hasta-el-buscaminas/#footnote_0_20735" id="identifier_0_20735" class="footnote-link footnote-identifier-link" title="Aunque &amp;#8220;sistema&amp;#8221; es masculino, y por lo tanto tambi&eacute;n deber&iacute;a serlo BIOS, todo el mundo dice &amp;#8220;la BIOS&amp;#8221;, en femenino&amp;#8230; no s&eacute; por qu&eacute;.">1</a>]</sup> y lo que es es un programa, proporcionado por el fabricante del ordenador, que tiene lo básico para arrancar. Y está en esa posición 0&#215;00000000 porque el fabricante la ha puesto ahí adrede.</p>

<div id="attachment_30276" class="wp-caption aligncenter" style="width: 650px"><img class="size-full wp-image-30276" title="j_computador_sofuncionamiento_bios" src="http://eltamiz.com/elcedazo/wp-content/uploads/2013/01/j_computador_sofuncionamiento_bios.jpg" alt="" width="640" height="480" /><p class="wp-caption-text">BIOS típica de un PC (Flickr de CaneHappy, cc-by-sa-2.0)</p></div>

<p>Esa BIOS, nada más arrancar, configura el puntero de la pila (para poder manejar interrupciones y subrutinas a partir de ahora) y empieza a ejecutar su programa:</p>

<ul>
    <li>Configura el vector de interrupciones para atender ella todas las interrupciones</li>
    <li>Hace un análisis básico del hardware que tiene el ordenador: comprueba cuánta memoria tiene, qué discos, qué tarjeta gráfica&#8230;</li>
    <li>Arranca el cargador de arranque (veremos esto luego)</li>
</ul>

<p>¿No os parece que hace muchas cosas que hace el sistema operativo? Bueno, no del todo. De todo lo que hacía el sistema operativo, la BIOS prácticamente solamente sabe hacer la gestión de los dispositivos, y además solo de un conjunto muy limitado de ellos: teclado y pantalla básica; a veces también ratón o tarjeta de red.<sup>[<a href="https://eltamiz.com/elcedazo/2014/08/02/computador-magico-xxxi-arranque-hasta-el-buscaminas/#footnote_1_20735" id="identifier_1_20735" class="footnote-link footnote-identifier-link" title="No obstante, s&iacute; es verdad que las BIOS modernas empiezan a ser cada vez m&aacute;s sofisticadas, incluso con navegadores web y sistema de ficheros.">2</a>]</sup></p>

<p>El caso es que la BIOS ya se está ejecutando y tratará de &#8220;arrancar&#8221; de un dispositivo. Esto se puede configurar, pero lo normal es que acabe arrancando de un disco duro. Así que lo que hace es irse al primer sector del disco duro seleccionado, leer todo lo que hay ahí y ponerlo en memoria. Eso es lo que se llama el &#8220;sector de arranque&#8221; del disco.</p>

<p>¿Y qué es lo que hay en ese sector de arranque? Pues lo que el usuario haya puesto ahí, claro&#8230; pero lo normal es que ahí haya un cargador de arranque (en inglés, <em>bootloader</em>).</p>

<p>¿Qué es el <em>bootloader</em>? El <em>bootloader</em> es otro programa, proporcionado por el fabricante del sistema operativo, que sabe cómo arrancar dicho sistema operativo. <em>Bootloaders</em> habituales en el mundillo Linux son LILO o GRUB; en el mundillo Microsoft probablemente ni siquiera seas consciente de que existe este cargador, porque no lo ves, pero también existe.</p>

<p>Así que de una forma u otra, el <em>bootloader</em> ha arrancado al sistema operativo (en nuestro ejemplo, alguna de las versiones de MS Windows). El sistema operativo, cuando arranca, configura su propio vector de interrupciones (eliminando la configuración que había puesto ahí la BIOS), detecta y configura todos los dispositivos que tiene, inicializa los módulos de gestión de procesos, de memoria y el sistema de ficheros y finalmente crea unos cuantos procesos: el gestor de impresiones, el de <em>logon</em>, el de red, el <em>indexador</em>&#8230; en fin, muchos procesos. Fíjate en que todos estos procesos son importantísimos, porque sin ellos el sistema operativo queda cojo, pero desde el punto de vista del módulo de gestión de procesos son un proceso más, no son diferentes de los procesos que ejecutará el usuario más adelante.</p>

<p>Uno de esos procesos será el encargado del <em>logon</em> del usuario, que típicamente le pedirá al usuario un nombre y una contraseña a través del teclado. El usuario mete su nombre y su contraseña y el sistema lanza otro montón de procesos&#8230; pero ahora esos procesos pertenecen al usuario. Entre ellos, ejecutará algún tipo de intérprete de comandos. Antiguamente, el intérprete de comandos era una línea de comandos, textual, en la que el usuario iba poniendo órdenes con el teclado; ahora lo normal es que esos comandos se den de forma gráfica, señalando con el cursor del ratón a un icono y haciéndole doble click, o algo similar.</p>

<p>El caso es que el usuario hace doble click en el icono del Buscaminas y el sistema operativo arranca el Buscaminas.</p>

<div id="attachment_30277" class="wp-caption aligncenter" style="width: 626px"><img class="size-full wp-image-30277" title="j_computador_buscaminas_buscaminas" src="http://eltamiz.com/elcedazo/wp-content/uploads/2013/01/j_computador_buscaminas_buscaminas.png" alt="" width="616" height="409" /><p class="wp-caption-text">Buscaminas de Microsoft</p></div>

<p>¿Y qué significa eso de <em>arrancar el Buscaminas</em>? En <a href="http://eltamiz.com/elcedazo/2013/09/11/computador-magico-xxii-ordenador-c16a-ii-funcionamiento/" target="_blank" class="liinternal">un capítulo muy muy lejano</a> dijimos que no te preocuparas de cómo llegaban a la memoria los programas, que lo explicaríamos más adelante&#8230; bueno, pues el momento ha llegado&#8230; y estoy seguro de que eras capaz de deducirlo tú solo. Atento, porque esto no es solo la forma en que se carga el Buscaminas, sino cualquier otro programa, incluidos los que hemos visto que se lanzan durante el arranque del sistema operativo.</p>

<p>En realidad es muy sencillo: cuando se quiere cargar un programa, el módulo de gestión de procesos crea un proceso. Luego se lee el contenido del fichero ejecutable del disco (utilizando los servicios del módulo de sistema de ficheros, que a su vez utilizará los del sistema de gestión de dispositivos) y lo escribe en memoria principal (utilizando los servicios del módulo de gestión de memoria). Finalmente, se configura el contador de programa del proceso para que apunte al área de memoria recién escrita&#8230; <em>et voilà!</em> La próxima vez que le toque el turno a este proceso, ejecutará las instrucciones que había en el fichero ejecutable.<sup>[<a href="https://eltamiz.com/elcedazo/2014/08/02/computador-magico-xxxi-arranque-hasta-el-buscaminas/#footnote_2_20735" id="identifier_2_20735" class="footnote-link footnote-identifier-link" title="En realidad nos hemos saltado un paso intermedio, en el que el proceso creado es una copia del que lo cre&oacute;, pero para el nivel de este art&iacute;culo eso no es necesario.">3</a>]</sup></p>

<p>Y ya está: ya puedes jugar al Buscaminas hasta que te canses; en ese momento decidirás cerrar el programa (seguramente haciendo click en la &#8220;x&#8221; de la parte superior derecha de la ventana), y en ese momento el programa informa al sistema de que debe finalizar. El sistema operativo, en concreto su gestor de procesos, elimina entonces la entrada que hacía referencia al programa de la lista de procesos, y el programa desaparece&#8230; hasta que vuelvas a hacer doble click en su icono, cuando todo vuelve a comenzar.</p>

<p>En el próximo (y último capítulo) veremos un resumen y daremos referencias para quien quiera profundizar.</p>

<p>&nbsp;</p>
<ol class="footnotes"><li id="footnote_0_20735" class="footnote">Aunque &#8220;sistema&#8221; es masculino, y por lo tanto también debería serlo BIOS, todo el mundo dice &#8220;la BIOS&#8221;, en femenino&#8230; no sé por qué.</li><li id="footnote_1_20735" class="footnote">No obstante, sí es verdad que las BIOS modernas empiezan a ser cada vez más sofisticadas, incluso con navegadores web y sistema de ficheros.</li><li id="footnote_2_20735" class="footnote">En realidad nos hemos saltado un paso intermedio, en el que el proceso creado es una copia del que lo creó, pero para el nivel de este artículo eso no es necesario.</li></ol>]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2014/08/02/computador-magico-xxxi-arranque-hasta-el-buscaminas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<item>
		<title>Computador mágico XXX &#8211; Sistema operativo II: funcionamiento</title>
		<link>https://eltamiz.com/elcedazo/2014/06/22/computador-magico-xxx-sistema-operativo-ii-funcionamiento/</link>
		<comments>https://eltamiz.com/elcedazo/2014/06/22/computador-magico-xxx-sistema-operativo-ii-funcionamiento/#comments</comments>
		<pubDate>Sun, 22 Jun 2014 12:59:18 +0000</pubDate>
		<dc:creator>J</dc:creator>
				<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[J]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=20368</guid>
		<description><![CDATA[La serie &#8220;El computador mágico&#8221; está disponible también en forma de libro. En el último capítulo de esta serie vimos la evolución histórica de los sistemas operativos, y vimos cómo nacían los cuatro componentes más importantes de los sistemas operativos. Lógicamente, no todos los sistemas operativos son iguales. No es lo mismo el sistema operativo de [...]]]></description>
			<content:encoded><![CDATA[<div align="left">
<table class="bookBox" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<td valign="center">
<p style="text-align: center; margin-top: 1px; margin-bottom: 1px; margin-left: 1px;" align="center"><a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liimagelink"><img class="aligncenter size-full wp-image-18513" title="Computador mágico" src="http://eltamiz.com/elcedazo/wp-content/uploads/2016/01/ComputadorMagicoDigest_v21_cover_v1_front2.png" alt="" width="90" height="128" /></a></p>
</td>
<td valign="center">

<p style="text-align: left;" align="center">
La serie &#8220;El computador mágico&#8221; está disponible también <a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liinternal">en forma de libro</a>.
</p>
</td>
</tr>
</tbody>
</table>
</div>

<p>En el <a href="http://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/" target="_blank" class="liinternal">último capítulo</a> de <a href="http://eltamiz.com/elcedazo/series/computador-magico/" target="_blank" class="liinternal">esta serie</a> vimos la evolución histórica de los sistemas operativos, y vimos cómo nacían los cuatro componentes más importantes de los sistemas operativos. Lógicamente, no todos los sistemas operativos son iguales. No es lo mismo el sistema operativo de un mainframe que el de tu Nintendo DS, el del cajero automático del banco que el de tu teléfono móvil, el de los servidores de Amazon que el que lleva tu televisor&#8230; pero casi todos ellos comparten un conjunto de tareas:</p>

<ul>
    <li>Gestión de dispositivos</li>
    <li>Gestión de procesos</li>
    <li>Gestión de memoria</li>
</ul>

<p>Todo lo que vamos a ver en este artículo ya lo hemos visto, aquí simplemente vamos a pegarlo todo para formar un sistema operativo. No todos los sistemas operativos contienen todos estos componentes, o incluso aunque los tengan pueden ser más o menos sofisticados, así que tendremos que contar cosas más o menos generales.</p>

<h2>Separación de privilegios</h2>

<p>Ya vimos anteriormente que los procesadores modernos tienen dos modos de funcionamiento distintos: uno <strong>normal</strong> y otro <strong>privilegiado</strong>. El sistema operativo se ejecuta sobre todo en modo privilegiado, mientras que las aplicaciones se ejecutan siempre en modo normal: cuando necesitan hacer algo privilegiado no lo hacen directamente, sino que se lo piden al sistema operativo, que lo hará, o no lo hará, o lo hará, pero más tarde, o lo que corresponda, dependiendo de muchas cosas que ya veremos (y de muchas otras que no veremos).</p>

<p>Aunque este concepto ya lo hemos visto <a href="http://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/" target="_blank" class="liinternal">antes</a>, vamos a volver a contar lo más importante aquí para que lo puedas contextualizar con el resto del artículo.</p>

<p>Las instrucciones privilegiadas más importantes son:</p>

<ul>
    <li>Configuración de las interrupciones</li>
    <li>Configuración de la pila</li>
    <li>Configuración de los elementos hardware que controlan el resto de componentes</li>
    <li>Operaciones de entrada y salida hacia y desde los periféricos</li>
</ul>

<p>Las instrucciones normales más importantes son:</p>

<ul>
    <li>Operaciones aritméticas y lógicas</li>
    <li>Traer y llevar datos a y desde la memoria principal&#8230; pero solo de la memoria que sea mía (ya veremos eso)</li>
    <li>Poner y quitar datos en la pila&#8230; pero no configurarla (eso lo vimos antes)</li>
    <li>Saltos y subrutinas&#8230; pero no a zonas de la memoria que no son mías (otra vez)</li>
    <li>Interrupción software o petición al sistema; por si no la recuerdas, esta instrucción era como una interrupción más, que saltaba a una posición conocida (en la cual quien estaba era el sistema operativo)</li>
</ul>

<h2>Funcionamiento basado en interrupciones</h2>

<p>Este concepto también lo hemos visto <a href="http://eltamiz.com/elcedazo/2014/03/22/computador-magico-xxvii-ordenador-c16c-interrupciones/" target="_blank" class="liinternal">antes</a>, pero vamos a enfatizarlo aquí: en un sistema operativo moderno, todo ocurre porque ha llegado una interrupción (salvo la inicialización, claro).</p>

<p>Cuando el ordenador arranca (más adelante veremos todo el proceso de arranque), a quien está ejecutando es al sistema operativo, que durante su inicialización configura la pila, configura todos los dispositivos que tiene y, lo más importante desde este punto de vista, configura el vector de interrupciones. El <strong>vector de interrupciones</strong> contiene la dirección de memoria que debe ejecutarse cuando ocurra cada interrupción. La gracia es que quien está en esas posiciones de memoria es siempre el sistema operativo, de modo que será siempre siempre el sistema operativo quien atienda cualquier interrupción.</p>

<p>Podemos dividir las interrupciones en los siguientes grupos:</p>

<ul>
    <li>La interrupciones generadas por los dispositivos: siempre que un dispositivo (por ejemplo un teclado, un disco duro, una tarjeta de sonido&#8230;) quiere decirle algo a la CPU, levanta una interrupción, y ahí está el sistema operativo para procesarla.</li>
    <li>Una particular de las anteriores: un reloj. Los ordenadores tienen un reloj que genera interrupciones cada cierto tiempo (como ejemplo, digamos que cada 1ms)&#8230; cada vez que el reloj genera una interrupción, ahí está el sistema operativo para hacer algo.<sup>[<a href="https://eltamiz.com/elcedazo/2014/06/22/computador-magico-xxx-sistema-operativo-ii-funcionamiento/#footnote_0_20368" id="identifier_0_20368" class="footnote-link footnote-identifier-link" title="No confundir este reloj con el reloj del procesador, que va a 1GHz o algo de ese orden de magnitud. Este es un reloj espec&iacute;fico para generar estas interrupciones.">1</a>]</sup></li>
    <li>La interrupción software: siempre que una aplicación de usuario necesita pedirle alguna cosa al sistema operativo, lanza una interrupción software, y ahí está el sistema operativo para procesar la petición.</li>
    <li>Las interrupciones debidas a error: cuando ocurre un error, los propios componentes del ordenador generan una interrupción&#8230; y ahí está el sistema operativo para hacer algo al respecto, si puede.</li>
</ul>

<h2>Gestión de procesos</h2>

<p>Las gestión de procesos, como su propio nombre indica, se encarga de gestionar procesos. ¿Y qué es un proceso? Pues&#8230; un proceso es la unidad mínima que gestiona el componente de gestión de procesos. Está bien, eso es una definición tautológica, así que que, para la profundidad que vamos a darle a este texto, vamos a decir que un proceso es un programa: el navegador, el lector de correo, tu procesador de textos&#8230; pero también muchos otros procesos que el ordenador necesita para funcionar y que probablemente ni siquiera sabes que existen.</p>

<div id="attachment_30264" class="wp-caption aligncenter" style="width: 476px"><img class=" wp-image-30264 " title="j_computador_sofuncionamiento_procesos" src="http://eltamiz.com/elcedazo/wp-content/uploads/2014/06/j_computador_sofuncionamiento_procesos1.png" alt="" width="466" height="458" /><p class="wp-caption-text">Parte del árbol de procesos en un Windows 7, obtenido con Process Explorer</p></div>

<p>Por lo tanto, tal y como <a href="http://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/" style="font-size: 13px;" target="_blank" class="liinternal">hemos visto</a>, la función más importante de la gestión de procesos es ir asignando la CPU a los procesos cada vez que les toca. El sistema de gestión de procesos tiene una lista con todos los procesos del sistema y su estado. Cuando un proceso esté realizando una operación de entrada/salida (que ya hemos visto que tardan mucho), el sistema de gestión de procesos lo saca de la CPU, busca uno que esté listo para ejecutar y lo pone en la CPU. También realiza esa operación periódicamente, usando el reloj que describíamos más arriba: cada 1ms (por ejemplo) saca de la CPU al proceso que esté y pone al siguiente en la lista (habitualmente esto se puede combinar con algún tipo de gestión de prioridad, por ejemplo como se puede ver en Windows 7 en la siguiente figura).</p>

<div id="attachment_30265" class="wp-caption aligncenter" style="width: 404px"><img class=" wp-image-30265 " title="j_computador_sofuncionamiento_procesosprioridad" src="http://eltamiz.com/elcedazo/wp-content/uploads/2014/06/j_computador_sofuncionamiento_procesosprioridad.png" alt="" width="394" height="182" /><p class="wp-caption-text">Asignación de prioridad de un proceso, en Process Explorer</p></div>

<p>¿Y qué significa eso de &#8220;sacar al proceso de la CPU&#8221; o &#8220;poner al proceso en la CPU&#8221;? Eso es lo que se llama un <strong>cambio de contexto</strong>. Cuando sacamos un proceso de la CPU, queremos que, cuando luego lo volvamos a meter, continúe por donde iba, exactamente con el mismo estado, como si nada hubiera pasado entre medias. Lo que haya que guardar exactamente depende del procesador y del sistema operativo, pero lo habitual es que haya que guardar el contador de programa PC, el puntero de la pila SP y todos los registros que tenga la CPU (a menudo hay que guardar alguna cosa más, pero son cosas que no hemos visto). Los tomamos con mucho cuidado y los guardamos en la descripción de nuestro proceso. Luego, cuando queramos volver a poner ese proceso en la CPU, simplemente volvemos a copiar esos datos desde la descripción del proceso a la CPU y seguimos ejecutando por donde dijera el PC: desde el punto de vista del proceso que se estaba ejecutando, no ha cambiado nada, para él todo sigue como estaba.</p>

<p>Así, un proceso es una cosa abstracta, un hilo de ejecución, un programa, que vamos &#8220;poniendo en la CPU&#8221; de vez en cuando.</p>

<h2>Gestión de memoria</h2>

<p>Cuando diseñamos nuestro ordenador, la memoria simplemente estaba ahí, lista para ser usada por la CPU. Pero ahora queremos que distintos procesos accedan a distintas partes de la memoria, pero no a otras. Más aún: aunque no lo hemos visto, en general queremos que cada proceso vea toda la memoria como si fuera toooooda para él, como si él fuera el único proceso ejecutándose en la máquina.</p>

<p>Para ello necesitamos introducir un nuevo componente hardware, situándolo entre la CPU y la memoria principal. Vamos a llamar a este componente MMU (<em>Memory Management Unit</em>, unidad de gestión de memoria); todas las CPUs modernas tienen una MMU.</p>

<p>Cuando la MMU se ve desde la CPU, se comporta como si fuera directamente la memoria principal MP. Es decir, la CPU le pide la posición 0xA1B2C3D4 y le da su contenido; le pide guardar algo en la posición 0xE5F6A7B8 y lo guarda. ¿Cómo lo hace? Mandándolas a la MP, obviamente, no puede hacerlo de otro modo.</p>

<p>La gracia está en que el mapeo en la posición que me pide la CPU y la posición correspondiente en la MP es configurable. Así, yo puedo configurar la MMU para decirle: siempre que te pidan las posiciones desde la 0&#215;00000000 a la 0x0000FFFF, utiliza en realidad las que van desde 0xA0000000 a 0xA000FFFF. Y así para todas las posiciones de memoria posibles. El truco está en que el módulo de gestión de memoria decide hacer mapeos distintos para procesos distintos, de modo que cada vez que el sistema de gestión de procesos mete un proceso en la CPU, también cambia la configuración de la MMU para que el proceso en cuestión crea que tiene toda la memoria disponible, pero en realidad solo pueda acceder a las posiciones que tiene asignadas. Eso quiere decir que los procesos ya no pueden simplemente acceder a la memoria, sino que antes de hacerlo deben pedírsela al sistema operativo, y tienen que &#8220;liberarla&#8221; cuando hayan terminado de usarla.</p>

<div id="attachment_30266" class="wp-caption aligncenter" style="width: 624px"><img class=" wp-image-30266 " title="j_computador_sofuncionamiento_memoria" src="http://eltamiz.com/elcedazo/wp-content/uploads/2014/06/j_computador_sofuncionamiento_memoria.png" alt="" width="614" height="337" /><p class="wp-caption-text">Estado de la memoria en un Windows 7</p></div>

<h2>Gestión de dispositivos</h2>

<p>Hemos visto que una de las funciones más importantes del sistema operativo es abstraer el uso de los dispositivos: nosotros usamos de la misma manera un teclado Logitech y uno de Trust, una pantalla de HP y una de LG, un disco duro Seagate y uno de Western Digital, una tarjeta gráfica de MSI y una de AMD&#8230;</p>

<p>Así que el sistema operativo agrupa los dispositivos por categorías y define una forma estándar de usarlo. Y luego cada fabricante de dispositivos proporciona una piececita de software para traducir esa forma estándar a lo que su dispositivo específico necesita. Esa piececita es lo que se llama un <strong>driver de dispositivo</strong>.</p>

<div id="attachment_30267" class="wp-caption aligncenter" style="width: 396px"><img class="size-full wp-image-30267" title="j_computador_sofuncionamiento_dispositivos" src="http://eltamiz.com/elcedazo/wp-content/uploads/2014/06/j_computador_sofuncionamiento_dispositivos.png" alt="" width="386" height="721" /><p class="wp-caption-text">Vista parcial de dispositivos en un PC con Windows 7</p></div>

<p>Además, el sistema operativo se encarga de que los dispositivos se utilicen de forma ordenada.</p>

<p>Vamos a ver el ejemplo de una tarjeta de sonido, que tiene tanto entrada (el conector del micrófono) como salida (la salida de línea que conectamos a los altavoces). Cuando un proceso en cuestión necesita reproducir sonido no se pone directamente a enviarle datos a la tarjeta de sonido (recuerda que, como <a href="http://eltamiz.com/elcedazo/2013/07/18/computador-magico-xix-pantalla-sencilla/" target="_blank" class="liinternal">hemos visto</a>, probablemente enviar sonido a la tarjeta sea algo tan &#8220;sencillo&#8221; como escribir una cierta información en unas determinadas posiciones de memoria). Si lo intentara, no podría, porque la MMU o la propia separación de privilegios de la CPU se lo impedirían. En lugar de eso, cuando necesita enviar sonido a la tarjeta, deja los sonidos (debidamente codificados) en la pila y genera una interrupción software.</p>

<p>Sabemos que quien atenderá esa interrupción será siempre el sistema operativo, en concreto su módulo de gestión de dispositivos, que tomará los sonidos que hay en la pila, y se los dará al driver de la tarjeta de sonido, que, ahora sí, los enviará a la tarjeta de sonido, que los reproducirá.</p>

<p>En el sentido contrario es parecido. Cuando un proceso necesita recibir sonido del micrófono (por ejemplo, porque sea un programa de videoconferencia) utiliza la interrupción software para decirle al sistema operativo &#8220;eh, a partir de ahora quiero recibir el sonido del micrófono; cuando tengas algo dáselo a esta subrutina mía&#8221;. Y el sistema operativo se lo apuntará en una tabla. Cuando ahora llegue sonido a través del micrófono, ¿qué hará la tarjeta? Generará una interrupción, que atenderá el sistema operativo (en realidad, quizá lo haga el driver del fabricante, pero eso es parte del sistema operativo); el sistema recibirá el sonido de la tarjeta y se lo dará a la subrutina en cuestión del proceso en cuestión.</p>

<h2>Sistema de ficheros</h2>

<p>Existe un componente más que, por su importancia, suele nombrarse aparte: el sistema de ficheros. Todos lo hemos usado alguna vez, así que seguro que lo entiendes rápido.</p>

<div id="attachment_30268" class="wp-caption aligncenter" style="width: 701px"><img class="size-full wp-image-30268" title="j_computador_sofuncionamiento_ficheros" src="http://eltamiz.com/elcedazo/wp-content/uploads/2014/06/j_computador_sofuncionamiento_ficheros.png" alt="" width="691" height="710" /><p class="wp-caption-text">Vista parcial de un sistema de ficheros en Windows 7</p></div>

<p>En los discos duros no se lee y escribe directamente, ni siquiera a través del driver correspondiente, sino que el sistema operativo ofrece un nivel de abstracción más: los ficheros. El sistema operativo ofrece el concepto de fichero como una sucesión de bytes, y el de directorio (o carpeta, en terminología Microsoft) para organizar ficheros, y luego ofrece formas de acceder a ellos, de listar su contenido, de abrirlo y cerrarlo&#8230;</p>

<p>No podemos entrar en mucha profundidad, porque cada sistema de ficheros es distinto y contar los detalles llevaría un libro completo. Así que vamos a ver por encima cómo funciona uno de los sistemas de ficheros más extendidos: FAT (existen otros, mucho más sofisticados y potentes, pero también mucho más difíciles de entender). Probablemente uses el sistema de ficheros de tipo FAT en un montón de sitios, sobre todo en tarjetas de memoria o pendrives USB.</p>

<p>Para empezar a explicarlo hay que entender que los discos no se leen byte a byte, sino bloque a bloque (de hecho, se les llama genéricamente así, dispositivo de bloque, tanto si son un disco magnético clásico como un pendrive, un CDROM o cualquier cosa que pueda parecer un disco). El tamaño de dichos bloques depende de la tecnología y el fabricante, pero supongamos que se leen en bloques de 1kB (1024 bytes) y que nuestro disco es pequeñito, de solo 16kB.</p>

<p><img class="aligncenter size-full wp-image-30269" title="j_computador_sofuncionamiento_fat" src="http://eltamiz.com/elcedazo/wp-content/uploads/2014/06/j_computador_sofuncionamiento_fat.png" alt="" width="518" height="395" /></p>

<p>&nbsp;</p>

<p>Lo que tenemos son 16 bloques de 1kB cada uno. El primero de ellos es un poco especial, porque lo que contiene es la tabla de asignación de ficheros (en inglés, <em>File Asignation Table</em>&#8230; FAT&#8230; de ahí el nombre). Y ahora supongamos que tenemos un fichero llamado &#8220;leeme.txt&#8221; que en su descripción dice que su primer bloque es el 2. Así que sabemos que está en el bloque 2 y quizá en alguno más. Nos vamos a la tabla de asignación del ficheros del primer bloque y vemos que en la posición 2 hay un 11&#8230; eso quiere decir que continúa en el 11. Ya tenemos el 2 y el 11. Miramos en la posición 11 y vemos un 8, así que continúa en el 8. Seguimos buscando así y tenemos el 7 y un -1. El -1 indica que se ha terminado, así que ya sabemos que el fichero &#8220;leeme.txt&#8221; está en los bloques 2, 11, 8 y 7. Así que cuando queramos leer ese fichero, esos son los bloques que debemos pedirle al disco duro.</p>

<p>De esta forma tan tonta funciona el sistema de ficheros FAT, y por eso se usa tanto en aparatos sencillos: porque es muy fácil de implementar.</p>

<h2>¿Y en realidad?</h2>

<p>Pues en realidad es un poco más complejo. Los sistemas de ficheros son mucho más sofisticados, y de hecho puedes tener más de uno a la vez; los drivers de dispositivos pueden ser millones, y en realidad hay dispositivos que ni siquiera funcionan exactamente así (como pueden ser las impresoras); no todas las tareas del sistema operativo se hacen durante las interrupciones; gestionar memoria y procesos es mucho más complicado de lo que hemos visto aquí; en fin&#8230; esto es una introducción. Lo que aquí hemos contado en un solo artículo puede representar un libro completo o un curso completo en cualquier carrera universitaria del ramo&#8230; pero lo fundamental lo tienes ahí. Cuando demos referencias al final podrás profundizar más, si lo deseas.</p>

<p>En el próximo capítulo veremos cómo arrancar el ordenador.</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
<ol class="footnotes"><li id="footnote_0_20368" class="footnote">No confundir este reloj con el reloj del procesador, que va a 1GHz o algo de ese orden de magnitud. Este es un reloj específico para generar estas interrupciones.</li></ol>]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2014/06/22/computador-magico-xxx-sistema-operativo-ii-funcionamiento/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<item>
		<title>Computador mágico XXIX &#8211; Sistema operativo I: historia</title>
		<link>https://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/</link>
		<comments>https://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/#comments</comments>
		<pubDate>Sat, 24 May 2014 10:13:42 +0000</pubDate>
		<dc:creator>J</dc:creator>
				<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[J]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=19173</guid>
		<description><![CDATA[La serie &#8220;El computador mágico&#8221; está disponible también en forma de libro. En el último capítulo de esta serie vimos las diferencias entre los ordenadores reales y los sistemas supersimplificados que hemos contado aquí para aprender, y vimos que muchas de esas diferencias solo se entendían como apoyo en su relación con el sistema operativo. [...]]]></description>
			<content:encoded><![CDATA[<div align="left">
<table class="bookBox" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<td valign="center">
<p style="text-align: center; margin-top: 1px; margin-bottom: 1px; margin-left: 1px;" align="center"><a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liimagelink"><img class="aligncenter size-full wp-image-18513" title="Computador mágico" src="http://eltamiz.com/elcedazo/wp-content/uploads/2016/01/ComputadorMagicoDigest_v21_cover_v1_front2.png" alt="" width="90" height="128" /></a></p>
</td>
<td valign="center">

<p style="text-align: left;" align="center">
La serie &#8220;El computador mágico&#8221; está disponible también <a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liinternal">en forma de libro</a>.
</p>
</td>
</tr>
</tbody>
</table>
</div>

<p>En el <a href="http://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/" target="_blank" class="liinternal">último capítulo</a> de <a href="http://eltamiz.com/elcedazo/series/computador-magico/" target="_blank" class="liinternal">esta serie</a> vimos las diferencias entre los ordenadores reales y los sistemas supersimplificados que hemos contado aquí para aprender, y vimos que muchas de esas diferencias solo se entendían como apoyo en su relación con el sistema operativo.</p>

<p>Pero, ¿qué es el <strong>sistema operativo</strong>? En el último capítulo esperábamos que tuvieras una idea más o menos intuitiva de lo que era un sistema operativo simplemente viendo los ejemplos de nuestra vida cotidiana: Windows, en todas su variantes, es un sistema operativo. Linux también lo es. Mac OS. Android, iOS,&#8230; en fin, esos son los ejemplos que a todos nos vienen a la mente rápidamente. En sistemas más grandes tenemos UNIX en todas sus variantes, así como los sistemas operativos de los mainframes de IBM y similares: z/OS (el antiguo MVS), DOS/VSE&#8230;</p>

<p>Así que ya tenemos claro lo que es un sistema operativo&#8230; ¿o no?</p>

<p>Pues no, no tanto. Y es que la discusión no es baladí, incluso con implicaciones legales y denuncias por abuso de monopolio de por medio.</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_sohistoria_esquema.png" class="liimagelink"><img class="aligncenter size-full wp-image-19175" title="j_computador_sohistoria_esquema" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_sohistoria_esquema.png" alt="" width="412" height="204" /></a></p>

<p>Existen muchas definiciones sobre lo que es el sistema operativo, casi tantas como libros que existen sobre el tema, pero nosotros vamos a intentar una más: <strong>el sistema operativo es la parte del software que se encarga de gestionar los recursos del ordenador a petición de las aplicaciones</strong>.</p>

<p>Supongo que te has quedado como estabas. O peor aún, porque antes lo tenías más o menos claro, y ahora quizá ya no tanto.</p>

<p>Así que vamos a intentar una aproximación histórica, a ver si poco a poco vamos centrando la definición. Para ello vamos a ver cómo eran y cómo se usaban los ordenadores inicialmente, y cómo el sistema operativo surgió casi por necesidad, más que por diseño.</p>

<p>Empezamos la batallita a mediados del siglo XX, justo después de que von Neumann diseñara su arquitectura. El que quería usar el ordenador se escribía su programa, iba allí, lo ejecutaba y listo. Al fin y al cabo, solamente unos pocos privilegiados tenían acceso a dicha máquina,<sup>[<a href="https://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/#footnote_0_19173" id="identifier_0_19173" class="footnote-link footnote-identifier-link" title="El UNIVAC 1, el primer ordenador con arquitectura Von Neumann.">1</a>]</sup> y menos aún sabían cómo hacer programas para ella, así que todo lo más había una pizarra donde se apuntaban para decir &#8220;eh, de 8 a 12 necesito usar el ordenador para calcular unos logaritmos&#8221; (salvo que lo necesitara el jefe entre medias, me imagino).</p>

<p>Supongo que rápidamente aparecerían las primeras bibliotecas de programas. No solo para operaciones matemáticas, sino también (y esta es la parte que nos interesa) para acceder a los dispositivos de entrada-salida: leer del teclado, escribir en la impresora (porque no, no había pantallas todavía), leer y escribir en las cintas magnéticas&#8230;  Si recuerdas cómo se escribía en nuestra rudimentaria pantalla, ¿imaginas lo complicado que debe ser escribir en una cinta magnética o en un teletipo? Una vez que has escrito la biblioteca de programas que lo hace, y encima funciona, no quieres volver a escribirla nunca más; ni siquiera a tus enemigos se lo deseas. Así que supongo que los afortunados que vivieron aquello probablemente compartirían esas bibliotecas: alguien creaba la biblioteca, la hacía sencilla de usar (dejando en el interior toda la complejidad de manejar los dispositivos de entrada-salida) y la dejaba a disposición de los demás.<sup>[<a href="https://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/#footnote_1_19173" id="identifier_1_19173" class="footnote-link footnote-identifier-link" title="Digo &amp;#8220;supongo&amp;#8221; con toda la intenci&oacute;n, porque no recuerdo haberlo le&iacute;do en ning&uacute;n sitio. Pero vaya, no parece una suposici&oacute;n descabellada.">2</a>]</sup> Es decir estas bibliotecas nacieron como una forma de <strong>abstraer el uso del hardware</strong>. Fíjate en que hasta aquí no &#8220;gestiona&#8221; dicho hardware, solo simplifica su uso.</p>

<p>También en esta época se empezaron a usar en los ordenadores las tarjetas perforadas,<sup>[<a href="https://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/#footnote_2_19173" id="identifier_2_19173" class="footnote-link footnote-identifier-link" title="Exist&iacute;an desde hac&iacute;a mucho tiempo para definir el patr&oacute;n que deb&iacute;an usar los telares.">3</a>]</sup> de modo que el científico-programador almacenaba cómodamente las tarjetas una vez perforadas en su despacho, y así cuando fuera a usar el ordenador perdería poco tiempo cargando el programa. ¡Hemos avanzado una barbaridad! Empezamos los años 50.</p>

<div id="attachment_19200" class="wp-caption aligncenter" style="width: 310px"><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_sohistoria_punched.jpg" class="liimagelink"><img class="size-medium wp-image-19200" title="j_computador_sohistoria_punched" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_sohistoria_punched-300x199.jpg" alt="" width="300" height="199" /></a><p class="wp-caption-text">Tarjetas perforadas (Marcin Wichary, cc-by-2.0, http://www.fotopedia.com/items/flickr-2210753092)</p></div>

<p>Pero, con el tiempo, cada vez más gente quería usar el ordenador, y cuando llegaban a usarlo no siempre estaba libre, así que tenían que esperar. De modo que entrenaron a un señor cuya misión era cargar el siguiente programa que estaba en la lista de espera en cuanto el que estaba ejecutándose hubiera terminado, y recoger la salida que hubiera generado para llevársela a quien había encargado el trabajo (<em><strong>job</strong></em> es como se llamaban esa tareas, <em>trabajo</em>, en inglés). Así que los científicos que querían usar el ordenador escribían su programa (o mejor dicho, lo perforaban en las tarjetas perforadas) y se lo daban al operario para que lo cargara, a la espera de que hubiera hueco libre para ejecutarlo. Por cierto que en esta época es cuando se inventaron los lenguajes de programación y los compiladores (FORTRAN, inicialmente). Estamos a finales de los 50. Pero, claro, rápidamente se pensó que se podía prescindir de ese ser humano cargador (<em>loader</em>, en inglés), y que los programas podían quedarse en el propio sistema, listos para ser ejecutados, pero a la espera de que terminara el que estuviera antes que ellos en la cola. Como la cola de una frutería, vamos. A esto se le llamó <strong>sistemas batch</strong> (<em>batch</em> es &#8220;lote&#8221; en inglés).</p>

<p>¿Y quién iba a encargarse de ir dando entrada a los programas según quedara hueco libre? Hubo que escribir algún &#8220;programa&#8221; un poco especial, que estuviera siempre cargado en la máquina, y que fuera ejecutándose cuando un programa &#8220;de usuario&#8221; terminase, pasando a ejecutar al siguiente en la cola. Había nacido el <strong>sistema operativo</strong>.</p>

<p>Pero también rápidamente se dieron cuenta de que ocurría un efecto curioso: cuando el programa tenía que hacer operaciones puramente de cálculo, estaba ahí, a todo trapo, ejecutando instrucciones sin parar. Pero cuando necesitaba interactuar con los dispositivos de entrada-salida (leer o escribir algún dato) se quedaba parado por largos periodos de tiempo mientras el dispositivo de entrada-salida hacía lo que le habían pedido hacer. No estamos refiriéndonos a nuestro ejemplo del teclado, en el que esperamos a que el usuario pulse una tecla. Ni que decir tiene que estos primeros programas no eran en absoluto interactivos, así que ni se pensaba en que el usuario pulsara alguna tecla mientras se ejecutaba el programa. A lo que me refiero es a la comunicación con otras máquinas. Piensa por ejemplo en una impresora a la que le das orden de hacer un salto de línea: la impresora tiene que encender un motor, girarlo unos cuantos grados (para mover el cilindro que arrastra el papel hasta la siguiente línea), luego moverlo hacia la derecha para que se posicione en la primera columna&#8230; ¿cuánto tarda en hacer eso? Que tarde del orden de un segundo, o incluso más, dependiendo del tipo de periférico que sea, no es descabellado.</p>

<p>Hasta para aquellos primitivos ordenadores, eso era muchísimo tiempo. Para que te hagas una idea, el IBM 360 original (de 1964) ejecutaba 34000 instrucciones por segundo; un ordenador de sobremesa puntero actual sobrepasa ampliamente los 10.000.000.000 de instrucciones por segundo, así que imagina lo que le da tiempo a hacer en 1ms&#8230; una barbaridad.</p>

<div id="attachment_19199" class="wp-caption aligncenter" style="width: 310px"><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_sohistoria_360.jpg" class="liimagelink"><img class="size-medium wp-image-19199  " title="j_computador_sohistoria_360" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_sohistoria_360-300x235.jpg" alt="" width="300" height="235" /></a><p class="wp-caption-text">Inauguración del primer IBM 360 instalado en Francia, en 1967 (Nicolas Roussel, cc-by-3.0, http://www.fotopedia.com/items/d66945df-37cc-4ce2-aa76-eb2ce9809ae7)</p></div>

<p>En paralelo se dio otro efecto, esta vez de negocio: los ordenadores ya no eran un juguete de los científicos, que hacían millones de operaciones matemáticas para calcular el trigésimo decimal de PI, sino equipos que usaban las grandes agencias gubernamentales, los grandes bancos, las grandes universidades&#8230; para su negocio. Por un lado, esa gente hacía muchas más operaciones de entrada-salida que los científicos, ya que sus ordenadores se solían usar para procesar grandes volúmenes de datos (que a menudo estaban en cintas magnéticas) en lugar de para realizar muchos cálculos matemáticos. Y, por otro, ya había que empezar a tener en cuenta el presupuesto&#8230; y el precio de ese ordenador tenía tantos ceros y había tanta gente a la cola esperando para usarlo que el coste de esas pausas, desperdiciadas simplemente esperando a que se rebobinara la cinta, empezaba a no ser despreciable.</p>

<p>Así que se les ocurrió lo siguiente: si tenemos programas en la cola, esperando para ser ejecutados, ¿por qué no vamos empezando con ellos en las pausas del programa que se está ejecutando? Con esto (principios de los setenta) nacieron los <strong>sistemas multiprogramados</strong>: más de un trabajo podía estar &#8220;<em>medioejecutándose</em>&#8221; a la vez. Obviamente, ejecutándose-ejecutándose de verdad, solo había uno, pero en cuando ese se quedaba esperando a alguna operación de entrada-salida, otro ocupaba inmediatamente su lugar en la CPU, para ir avanzando. Con esto nació la <strong>gestión de procesos</strong> tal y como la conocemos hoy (ya existía cierta gestión de procesos en la decisión de cargar un trabajo cuando el otro acababa, pero era poco más que gestionar una cola, como el Turn-O-Matic de la charcutería).</p>

<p>Pero claro, ahora ya teníamos varios programas a la vez en el ordenador. Imagina que a uno de ellos le da por escribir en una posición de memoria que es de otro programa. Ni siquiera estoy pensando en temas de seguridad o privacidad de los datos del otro programa, sino en simples errores. A lo mejor el &#8220;otro programa&#8221; era el cálculo de los impuestos del Departamento del Tesoro (el equivalente al Ministerio de Hacienda en España) y modificar por error un número allí podía tener consecuencias catastróficas (para alguien). Así que había que aislar unos programas de otros: la memoria de unos no podía ser vista por otros. Así que los programas se vieron forzados a pedirle por favor al sistema operativo que les diera memoria, a liberarla cuando terminasen, a no salirse de ella y cosas así. Había nacido la <strong>gestión de memoria</strong>.</p>

<p>Lo mismo ocurría respecto a la entrada/salida: ahora ya podía haber más de un programa que intentara por ejemplo imprimir, y, si se permitía, al final saldría todo embarullado por la impresora. Así que no se puede permitir que los programas impriman directamente, sino que deben pedirle al sistema operativo que imprima, y él ya lo hará cuando considere que no interfiere con los demás programas (y lo mismo, por supuesto, aplica al resto de dispositivos de entrada y salida: la pantalla, leer/escribir en cinta, en disco&#8230;). Es decir, el sistema operativo tuvo que empezar a <strong>gestionar el hardware</strong>.</p>

<p>Pero todo era aún muy rudimentario (desde nuestro punto de vista, claro). Macluskey cuenta siempre que el Sistema Operativo del ordenador en que comenzó a trabajar a mediados de los setenta sólo ocupaba 3 Kb en la memoria de la máquina. 3Kb: 3.000 octetos, así que imaginaros lo poquito que podía hacer con tan poco código. Los trabajos no eran nada interactivos: una vez empezaban, seguían hasta que acababan o hasta que daban un error&#8230; lo cual no era infrecuente. Si has programado alguna vez un simple &#8220;ahorcado&#8221;, ¿te puedes imaginar lo que puede ser programar eso en  FORTRAN o, peor aún, en ensamblador? La probabilidad de cometer un error era más bien una certeza. Pero el problema es que, aun con los sistemas multiprogramados, desde que tú enviabas el programa al ordenador hasta que volvía el resultado de su ejecución podían pasar horas o incluso días. Y todo para descubrir a lo peor que tenías un error de sintaxis en la cuarta línea del programa y que la espera no había servido de nada.<sup>[<a href="https://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/#footnote_3_19173" id="identifier_3_19173" class="footnote-link footnote-identifier-link" title="Yo me desespero cuando hoy en d&iacute;a una prueba tarda m&aacute;s de unos cuantos segundos, as&iacute; que me imagino lo que deb&iacute;a ser esperar hasta el d&iacute;a siguiente.">4</a>]</sup><sup>[<a href="https://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/#footnote_4_19173" id="identifier_4_19173" class="footnote-link footnote-identifier-link" title="Nota de Macluskey: Cuando no hab&iacute;as conocido otra cosa, no lo echabas de menos: as&iacute; era como se funcionaba, y punto. Usabas los tiempos muertos en escribir tu o tus siguientes programas&amp;#8230; en realidad tambi&eacute;n nosotros, los programadores de la &eacute;poca, &eacute;ramos multiprogramadores.">5</a>]</sup></p>

<p>Así que se buscó que los programadores pudieran utilizar el ordenador aún cuando ya hubiera un programa ejecutándose. La solución es muy sencilla: en los sistemas multiprogramados metíamos un programa de los de la cola cuando el principal hacía operaciones de entrada-salida&#8230; ¿por qué no hacemos ese cambio de forma obligada cada cierto tiempo? Mejor aún: si tengo 6 programas cargados, puedo darle la CPU primero al 1, luego al 2, luego al 3&#8230; así hasta el 6&#8230; y luego otra vez al 1, y al 2&#8230; y así continuamente. ¿No? Si hago eso, y lo hago lo bastante rápido (por ejemplo, cada 10ms) a todos los programas casi les parece que están continuamente ejecutándose, aunque en realidad vayan a saltos. <em>Grosso modo</em> ocurre que si hay 8 programas ejecutándose a ratitos en un ordenador de potencia 100 (signifique eso lo que signifique), casi casi le parece a cada uno de ellos que en realidad se está ejecutando él solo en un ordenador de potencia 12,5 (12,5=100/8). Habían nacido los <strong>sistema de tiempo compartido</strong>.<sup>[<a href="https://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/#footnote_5_19173" id="identifier_5_19173" class="footnote-link footnote-identifier-link" title="De hecho, debido al tiempo perdido en la entrada-salida, estad&iacute;sticamente a los programas les parece que es incluso mejor que 12,5.">6</a>]</sup></p>

<div id="attachment_19202" class="wp-caption aligncenter" style="width: 310px"><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_sohistoria_cray2.jpg" class="liimagelink"><img class="size-medium wp-image-19202" title="j_computador_sohistoria_cray2" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_sohistoria_cray2-300x225.jpg" alt="" width="300" height="225" /></a><p class="wp-caption-text">Ordenador Cray2, que en 1985 era el ordenador más potente del mundo&#8230; y permaneció el primero hasta 1990 (Matthew Phillips, cc-by-nd-2.0, http://ja.fotopedia.com/items/flickr-2456335311 ; expuesto en el Musée des arts et metiers de París)</p></div>

<p>Las posibilidades de esta aproximación fueron ingentes. No solo para los programadores, que ahora podían probar sus programas rápidamente, sino porque permitía hacer programas que utilizaran usuarios sin formación técnica. Era posible hacer programas interactivos: el programa podía pedirle al usuario que hiciera algo y actuar en consecuencia. Simplemente, mientras el programa estaba esperando a que el usuario tecleara sus datos nunca le tocaba la CPU y listo. El sistema operativo se encargaba de ello. Y cuando tenía trabajo que hacer, le iba tocando la CPU a ráfagas cortas y rápidas. Se desplegaron terminales, de forma que más de un usuario pudiera usar el ordenador a la vez, y se les pusieron los terminales en el despacho. Ahora ya era posible hacer editores de texto, hojas de cálculo, bases de datos interactivas,&#8230; ¡incluso juegos! Había nacido la informática moderna.</p>

<p>El resto&#8230; ya casi ni es historia. Los sistemas se miniaturizaron, se hicieron más baratos, su consumo energético se redujo, se inventaron los interfaces visuales, las redes&#8230; de forma que hoy en día llevas más potencia en tu teléfono móvil que aquellos primitivos ordenadores de von Neumann (pero no un poquito, no, sino muchos órdenes de magnitud más). Si eres un lector habitual de este blog, conoces la serie de Macluskey sobre la <a href="/elcedazo/series/historia-de-un-viejo-informatico/" target="_blank" class="liinternal">historia de la informática</a>. Y si no la conoces, ¿a qué estás esperando, alma de cántaro? Te estás perdiendo una de las mejores series que se ha escrito en El Cedazo.</p>

<p>En el próximo capítulo profundizaremos un poco más (solo un poco) en el funcionamiento del sistema operativo.</p>

<p>&nbsp;</p>
<ol class="footnotes"><li id="footnote_0_19173" class="footnote">El UNIVAC 1, el primer ordenador con arquitectura Von Neumann.</li><li id="footnote_1_19173" class="footnote">Digo &#8220;supongo&#8221; con toda la intención, porque no recuerdo haberlo leído en ningún sitio. Pero vaya, no parece una suposición descabellada.</li><li id="footnote_2_19173" class="footnote">Existían desde hacía mucho tiempo para definir el patrón que debían usar los telares.</li><li id="footnote_3_19173" class="footnote">Yo me desespero cuando hoy en día una prueba tarda más de unos cuantos segundos, así que me imagino lo que debía ser esperar hasta el día siguiente.</li><li id="footnote_4_19173" class="footnote">Nota de Macluskey: Cuando no habías conocido otra cosa, no lo echabas de menos: así era como se funcionaba, y punto. Usabas los tiempos muertos en escribir tu o tus siguientes programas&#8230; en realidad también nosotros, los programadores de la época, éramos <em>multiprogramadores</em>.</li><li id="footnote_5_19173" class="footnote">De hecho, debido al tiempo perdido en la entrada-salida, estadísticamente a los programas les parece que es incluso mejor que 12,5.</li></ol>]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2014/05/24/computador-magico-xxix-sistema-operativo-i-historia/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<item>
		<title>Computador mágico XXVIII &#8211; Ordenadores reales</title>
		<link>https://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/</link>
		<comments>https://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/#comments</comments>
		<pubDate>Sun, 20 Apr 2014 14:37:37 +0000</pubDate>
		<dc:creator>J</dc:creator>
				<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[J]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=19145</guid>
		<description><![CDATA[La serie &#8220;El computador mágico&#8221; está disponible también en forma de libro. Hemos dedicado los últimos capítulos de esta serie a ver unos ordenadores muy sencillitos, pero que capturaban la esencia de los ordenadores modernos. Como te imaginarás, los ordenadores reales son bastante más complejos, así que vamos a dedicar unas palabras a dar algunas [...]]]></description>
			<content:encoded><![CDATA[<div align="left">
<table class="bookBox" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<td valign="center">
<p style="text-align: center; margin-top: 1px; margin-bottom: 1px; margin-left: 1px;" align="center"><a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liimagelink"><img class="aligncenter size-full wp-image-18513" title="Computador mágico" src="http://eltamiz.com/elcedazo/wp-content/uploads/2016/01/ComputadorMagicoDigest_v21_cover_v1_front2.png" alt="" width="90" height="128" /></a></p>
</td>
<td valign="center">

<p style="text-align: left;" align="center">
La serie &#8220;El computador mágico&#8221; está disponible también <a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liinternal">en forma de libro</a>.
</p>
</td>
</tr>
</tbody>
</table>
</div>

<p>Hemos dedicado los últimos capítulos de <a href="http://eltamiz.com/elcedazo/series/computador-magico/" target="_blank" class="liinternal">esta serie</a> a ver unos ordenadores muy sencillitos, pero que capturaban la esencia de los ordenadores modernos. Como te imaginarás, los ordenadores reales son bastante más complejos, así que vamos a dedicar unas palabras a dar algunas pinceladas sobre las diferencias.</p>

<p>A diferencia de los capítulos anteriores, este será de mucho blah-blah-blah, mucha batallita. No creas, no obstante, que se trata de un capítulo trivial: algunas de las cosas que veremos serán importantes para los siguientes capítulos. De hecho, algunas de las cosas que veremos solo las nombraremos someramente, porque su importancia solo quedará patente cuando veamos los sistemas operativos más adelante. Eso quiere decir que si alguno de los párrafos te resulta un poco&#8230; inútil&#8230; como si no supieras muy bien por qué eso es importante&#8230; no te preocupes mucho, que profundizaremos en ello en el futuro.</p>

<p>&nbsp;</p>

<div id="attachment_19149" class="wp-caption aligncenter" style="width: 732px"><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_reales_atmel8051.png" class="liimagelink"><img class="size-full wp-image-19149" title="j_computador_reales_atmel8051" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_reales_atmel8051.png" alt="" width="722" height="791" /></a><p class="wp-caption-text">Diagrama del microcontrolador 8051 de Atmel (http://www.atmel.com/Images/doc4316.pdf)</p></div>

<p style="text-align: center;"></p>

<p style="text-align: left;">En el dibujo de cabecera puedes ver el diagrama del 8051 de Atmel. Los 8051 (y sus variantes) son unos de los microcontroladores más utilizados en sistemas empotrados, en pequeños proyectos amateur y de investigación, porque es baratísimo (alrededor de 1€) y tiene una comunidad de usuarios muy grande detrás.<sup>[<a href="https://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/#footnote_0_19145" id="identifier_0_19145" class="footnote-link footnote-identifier-link" title="Aunque en los &uacute;ltimos a&ntilde;os los sistemas basados en Arduino est&aacute;n tomando mucho empuje.">1</a>]</sup></p>

<p style="text-align: left;">El 8051 fue un microcontrolador diseñado por Intel en 1980. Es decir, que no es lo más de lo más en tecnología punta, pero ya es significativamente más complejo que los sistemas C16A, C16B y C16C que hemos visto nosotros. Así que no te digo nada si lo que intentáramos fuera estudiar un ordenador moderno, como los Intel Core i7&#8230;</p>

<p style="text-align: left;">¿Podemos ver algunas diferencias? Algunas ya las hemos ido viendo cuando veíamos la memoria o las interrupciones. Otras son solamente diferencias cuantitativas, como el tamaño de los buses y los registros; esas vamos a obviarlas, porque no suponen un cambio de concepto, simplemente tiene un tamaño distinto. Vamos a ver las diferencias que sí sean importantes.</p>

<p style="text-align: left;">Para empezar, es muy habitual que hoy en día ya no hablemos de un ordenador como un <strong>bloque monolítico</strong>, sino que se suelen comprar los <strong>componentes por separado</strong>: por un lado la CPU, por otro lado la memoria, por otro lado los dispositivos de entrada/salida&#8230; pero bueno, supongo que eso ya lo sabías, a estas alturas del siglo. Así que vamos a centrarnos en las diferencias más arquitecturales.</p>

<p style="text-align: left;">Las ALUs reales tienen muchísimas más operaciones que las que hemos visto aquí y las CPUs reales tienen también muchísimas más instrucciones.<sup>[<a href="https://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/#footnote_1_19145" id="identifier_1_19145" class="footnote-link footnote-identifier-link" title="Adem&aacute;s, como ya mencionamos en cap&iacute;tulos anteriores, en los sistemas modernos esas instrucciones est&aacute;n microprogramadas. No obstante, eso no afecta al nivel al que estamos viendo los ordenadores, as&iacute; que lo vamos a obviar.">2</a>]</sup> Nosotros hemos tenido que hacer una subrutina para hacer la operación &#8220;multiplicar&#8221;, pero no te sorprenderá que eso sea una instrucción que venga de serie en cualquier CPU que se precie. Por ejemplo, el 8051 de más arriba tiene en torno a un centenar de instrucciones, y ya estamos hablando de una CPU antigua. Las CPUs más modernas que esa tienen operaciones para coma flotante, operaciones multimedia, gestión de otros componentes de la CPU&#8230; Nosotros hemos visto cómo hacer la multiplicación era una operación muy habitual, y hacerla a base de una subrutina que haga operaciones más simples es un incordio, de modo que parece que proporcionar instrucciones que hagan operaciones más complejas parece buena idea. Bien, pues sí lo es. Y cuantas más, mejor.</p>

<p style="text-align: left;">¿No?</p>

<p style="text-align: left;">Pues no está tan claro. Aquí hay dos corrientes distintas, y cada una tiene sus ventajas. Por un lado tenemos la corriente <strong>CISC</strong> (<em>Complex Instruction Set Computer</em>, computador con juego de instrucciones complejo) y por otro tenemos <strong>RISC</strong> (<em>Reduced Instruction Set Computer</em>, computador con juego de instrucciones reducido). La corriente CISC, de la cual los procesadores Intel que usamos en nuestros ordenadores son probablemente el mayor exponente, pretende que la mayor cantidad posible de instrucciones se hagan en el nivel más bajo posible, de modo que puedan optimizarse y hacerse muy rápidas, mucho más rápidas que hacer subrutinas que hagan lo equivalente. Por ejemplo, nuestro editor Macluskey recuerda que uno de los ordenadores con los que él ha trabajado tenía una instrucción ensamblador que hacía la ordenación (SORT).<sup>[<a href="https://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/#footnote_2_19145" id="identifier_2_19145" class="footnote-link footnote-identifier-link" title="NdE: En concreto son las CPU&amp;#8217;s de los modernos mainframes de IBM, que tienen entre su juego de instrucciones&nbsp;una&nbsp;concreta para hacer un &amp;#8220;Insertion Sort&amp;#8221;.">3</a>]</sup></p>

<p style="text-align: left;">La corriente RISC, de la cual el mayor exponente ahora mismo serían los procesadores ARM que llevan casi todos los teléfonos móviles actuales, propugna en cambio que las instrucciones que ofrezca la CPU sean muy muy sencillas, pero muy muy eficientes. Puede parecer que los diseñadores de sistemas CISC no van a ser imbéciles y a hacer las instrucciones menos eficientes que los que diseñan RISC&#8230; pero no es eso lo que quiere decir. Lo que ocurre es que al reducir no solo la cantidad de instrucciones, sino también su tipo, se pueden aplicar optimizaciones que serían imposibles en CISC. Por ejemplo, en tecnología RISC se intentan evitar las instrucciones que operan con la memoria: solo las instrucciones que cargan y guardan cosas en memoria deben acceder a memoria; el resto de operaciones deben operar exclusivamente sobre los registros de la CPU (el equivalente a nuestro acumulador). El caso es que, efectivamente, con esas restricciones parece que es más fácil hacer las instrucciones sencillas más eficientemente.<sup>[<a href="https://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/#footnote_3_19145" id="identifier_3_19145" class="footnote-link footnote-identifier-link" title="Cuidado de todos modos: en esta discusi&oacute;n, la multiplicaci&oacute;n y cosas as&iacute; siguen siendo &amp;#8220;instrucciones sencillas&amp;#8221;.">4</a>]</sup> Al final ocurre que los procesadores RISC modernos tienen más instrucciones que los CISC antiguos, de modo que la R de <em>Reduced</em> hay que entenderla con cuidado: no es tanto que tenga pocas instrucciones como que dichas instrucciones sean muy sencillas.</p>

<p style="text-align: left;">Es esta una pelea que no está resuelta, y que además probablemente no se resolverá a medio plazo, pues obviamente cada una tiene sus aplicaciones.</p>

<p style="text-align: left;">Otra diferencia importante entre los ordenadores reales y nuestro C16C es la memoria. Nosotros hemos proporcionado una memoria principal y una memoria interna con la que trabajar (el acumulador). Pero las CPUs reales tienen:</p>

<ul>
    <li>Muchos <strong>más registros</strong> internos. Parecidos a nuestro acumulador, pero muchos más.</li>
    <li>La lectura y escritura en la memoria no suelen tardar un tick de reloj, sino muchos más.</li>
    <li>Para paliarlo, se suele introducir uno o más niveles de memoria intermedios entre la CPU y la memoria RAM, a los que se suele llamar <strong>memoria caché</strong>. Esta memoria caché es mucho más rápida que la memoria principal&#8230; y más cara, claro, y por eso suele ser muuucho más pequeña. Para lo que sirve es para almacenar temporalmente en ella las posiciones de memoria a las que se está accediendo muy a menudo, para que esos accesos sean más rápidos. Desde el punto de vista del programa, esta memoria caché suele ser transparente, en el sentido de que no se accede a ella directamente, sino como si fuera parte de la memoria principal. Si da la casualidad de que lo que buscamos está en esta caché, será muy rápida&#8230; pero desde el punto de vista del programa no hay diferencia.</li>
</ul>

<p>La tercera diferencia importante está en el acceso a los dispositivos de entrada/salida. En nuestro C16C los dispositivos de entrada/salida estaban directamente conectados al bus de memoria. Es decir, escribir en la pantalla era exactamente igual que escribir en la memoria. Pero en algunos sistemas (en particular en los procesadores Intel que casi todos tenemos en casa) existen dos buses A (y consecuentemente dos buses D): uno para la memoria principal y otro para la entrada/salida. Es decir, simplificándolo, tendría una arquitectura como la siguiente:</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_reales_doblebus.png" class="liimagelink"><img class="aligncenter size-full wp-image-19152" title="j_computador_reales_doblebus" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_reales_doblebus.png" alt="" width="795" height="422" /></a></p>

<p>Fíjate en que ahora tenemos un bus DM/AM (la M es de <em>Memory</em>, memoria) y otro bus DIO/AIO (IO es de <em>Input-Output</em>, entrada-salida). Lógicamente, donde antes había instrucciones ST y LD, ahora tiene que haber STM, STIO, LDM y LDIO. Ah, y un detalle más: si decíamos que el acceso a memoria no ocupaba un tick de reloj, sino muchos, el acceso a dispositivos de I/O ocupa muchísimos más. Si esos dispositivos de entrada salida implican movimientos físicos (como por ejemplo rebobinar una cinta magnética o mover el cabezal de un disco duro), el tiempo puede ser varios órdenes de magnitud mayor que un tick de reloj (esto tendrá implicaciones más adelante, cuando veamos cómo lo abordan los sistemas operativos).</p>

<p>La forma en que se accede a memoria es una cuarta diferencia, que no hemos visto hasta ahora. Como no afecta a cómo funciona el computador, solo vamos a nombrarlas por completitud (es decir, que si no entiendes muy bien lo que significan, no te obsesiones, que no es importante para seguir). Hasta ahora, cuando en nuestras instrucciones poníamos &lt;addr&gt;, significaba que allí estaba el dato con el que queríamos operar. Fácil. Es lo que se llama <strong>direccionamiento directo</strong>. Pero existen más formas de direccionamiento:</p>

<ul>
    <li><strong>Direccionamiento indirecto</strong>: la dirección a la que hace referencia el parámetro de la instrucción no contiene el valor con el que operar, sino la dirección en donde está el verdadero valor con el que operar. Si has programado en C (o en algún otro lenguaje de bajo nivel) esto es simplemente un puntero.</li>
    <li><strong>Direccionamiento indexado</strong>: la dirección efectiva en donde está el valor con el que operar se obtiene sumando la posición base más un índice. Es decir, es una forma de recorrer <em>arrays</em>.</li>
    <li><strong>Direccionamiento relativo</strong>: la dirección efectiva del operando se obtiene sumando la dirección en donde está la instrucción más el parámetro proporcionado (que podría ser negativo). Este mecanismo se puede usar para hacer código que se pueda mover de una posición de memoria a otra sin que deje de funcionar.</li>
</ul>

<p>Existe una última diferencia importante respecto al tratamiento de la memoria: la MMU (<em>Memory Management Unit</em>, unidad de gestión de memoria). Pero esa no la veremos hasta que no lleguemos a la parte de gestión de memoria de los sistemas operativos, porque si intento explicarla ahora solo va a confundirte.</p>

<p>La última diferencia importante se refiere al modo de ejecución. Supongo que estás acostumbrado a que tu ordenador tenga cierta separación de privilegios. Probablemente conoces lo que es el usuario <em>Administrador</em> (en Windows) o <em>root</em> (en Unix), y sabes que puede haber más usuarios. Y sabes que (a menos que haya un <em>bug</em>) un usuario no puede acceder a las cosas de otro. ¿Cómo puede hacer eso el ordenador? Con lo que hemos visto hasta ahora, una vez que se está ejecutando un programa, parece que tiene acceso a todo, que puede ejecutar todas las instrucciones&#8230; en particular, podría ejecutar instrucciones que accedan a los datos de otro usuario. ¿No? Pues no. La mayor parte de los sistemas modernos tienen algún mecanismo de separación de privilegios, de modo que, cuando la CPU está en <strong>modo normal</strong>, hay muchas instrucciones que no puede ejecutar. Si el programa que está ejecutando contiene esas instrucciones, dará un fallo o simplemente las ignorará. Y si está en <strong>modo privilegiado</strong>, entonces sí, puede ejecutarlas todas.</p>

<ul>
    <li>Ejemplos de instrucciones &#8220;privilegiadas&#8221;: gestión de la memoria, de acceso a los dispositivos de entrada-salida, de configuración de la pila, de configuración de las interrupciones&#8230; Una muy importante es precisamente &#8220;salir del modo privilegiado&#8221;.</li>
    <li>Ejemplos de instrucciones &#8220;normales&#8221;: operaciones aritméticas, operaciones lógicas, lectura y escritura de memoria (pero solo de determinadas zonas de memoria), saltos, subrutinas&#8230; y poco más. Ah, sí, hay una muy importante: la <strong>interrupción software</strong>.</li>
</ul>

<p>Vamos a presentar la interrupción software muy someramente, porque este es el lugar que corresponde, pero más adelante lo veremos en detalle. La interrupción software es como una interrupción de las que hemos visto antes, con la única diferencia de que no se dispara por un evento del hardware, sino porque se ejecuta la instrucción SWIRQ (por ponerle un nombre). Una vez que salte esa interrupción, se interrumpirá la ejecución de lo que esté haciendo, como siempre que hay una interrupción, y saltará a una posición de memoria conocida y pasará al modo privilegiado. La gracia es que quien reside en esa posición de memoria es el sistema operativo (que veremos más adelante), y configurar esa posición de memoria es una instrucción privilegiada, así que no puede haberlo hecho el usuario normal, tiene que haberlo hecho el propio sistema operativo durante su inicialización.</p>

<p>Al juntar ambas cosas, sabemos que tenemos dos modos: el modo normal, que es como se ejecutan todos los programas de usuario. Y el modo privilegiado, que es como se ejecuta el sistema operativo. Cuidado, porque este modo privilegiado no es el usuario <em>Administrador</em> o el usuario <em>root</em>. En ambos casos tanto <em>root</em> como <em>Administrador</em> ejecutan en modo normal. Lo del modo privilegiado es aún más profundo que eso. Ni siquiera el usuario <em>Administrador</em> puede ejecutar las instrucciones privilegiadas directamente, tiene que hacerlo a través del sistema operativo.</p>

<p>El caso es que estamos continuamente con el sistema operativo para acá, el sistema operativo para allá&#8230; hombre, lo he hecho porque a estas alturas de la película seguro que sabes lo que es un sistema operativo (Windows, Linux, Android, Mac, iOS&#8230; son nombres de sistemas operativos). Pero seguro que muchas de las cosas que vamos nombrando te quedan un poco en el aire. Pues a eso dedicaremos los siguientes capítulos: al sistema operativo.</p>

<p>&nbsp;</p>
<ol class="footnotes"><li id="footnote_0_19145" class="footnote">Aunque en los últimos años los sistemas basados en Arduino están tomando mucho empuje.</li><li id="footnote_1_19145" class="footnote">Además, como ya mencionamos en capítulos anteriores, en los sistemas modernos esas instrucciones están microprogramadas. No obstante, eso no afecta al nivel al que estamos viendo los ordenadores, así que lo vamos a obviar.</li><li id="footnote_2_19145" class="footnote">NdE: En concreto son las CPU&#8217;s de los modernos mainframes de IBM, que tienen entre su juego de instrucciones una concreta para hacer un &#8220;Insertion Sort&#8221;.</li><li id="footnote_3_19145" class="footnote">Cuidado de todos modos: en esta discusión, la multiplicación y cosas así siguen siendo &#8220;instrucciones sencillas&#8221;.</li></ol>]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2014/04/20/computador-magico-xxviii-ordenadores-reales/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<item>
		<title>Computador mágico XXVII &#8211; Ordenador C16C: interrupciones</title>
		<link>https://eltamiz.com/elcedazo/2014/03/22/computador-magico-xxvii-ordenador-c16c-interrupciones/</link>
		<comments>https://eltamiz.com/elcedazo/2014/03/22/computador-magico-xxvii-ordenador-c16c-interrupciones/#comments</comments>
		<pubDate>Sat, 22 Mar 2014 14:55:33 +0000</pubDate>
		<dc:creator>J</dc:creator>
				<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[J]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=19097</guid>
		<description><![CDATA[La serie &#8220;El computador mágico&#8221; está disponible también en forma de libro. En los últimos capítulos de esta serie nos hemos dedicado a estudiar cómo funciona un ordenador sencillo, sencillísimo, minimalista: el C16A. Luego lo ampliamos, inventando el ordenador C16B, para poder hacer llamadas a subrutinas. En la última entrada hablamos del compilador. Ahora vamos [...]]]></description>
			<content:encoded><![CDATA[<div align="left">
<table class="bookBox" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<td valign="center">
<p style="text-align: center; margin-top: 1px; margin-bottom: 1px; margin-left: 1px;" align="center"><a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liimagelink"><img class="aligncenter size-full wp-image-18513" title="Computador mágico" src="http://eltamiz.com/elcedazo/wp-content/uploads/2016/01/ComputadorMagicoDigest_v21_cover_v1_front2.png" alt="" width="90" height="128" /></a></p>
</td>
<td valign="center">

<p style="text-align: left;" align="center">
La serie &#8220;El computador mágico&#8221; está disponible también <a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liinternal">en forma de libro</a>.
</p>
</td>
</tr>
</tbody>
</table>
</div>

<p>En los últimos capítulos de <a href="http://eltamiz.com/elcedazo/series/computador-magico/" target="_blank" class="liinternal">esta serie</a> nos hemos dedicado a estudiar cómo funciona un ordenador sencillo, sencillísimo, minimalista: <a href="http://eltamiz.com/elcedazo/2013/08/24/computador-magico-xxi-ordenador-c16a-i-arquitectura-de-von-neumann/" target="_blank" class="liinternal">el C16A</a>. Luego lo ampliamos, inventando <a href="http://eltamiz.com/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/" target="_blank" class="liinternal">el ordenador C16B</a>, para poder hacer llamadas a subrutinas. En la última entrada hablamos del <a href="http://eltamiz.com/elcedazo/2014/02/08/computador-magico-xxvi-el-compilador/" target="_blank" class="liinternal">compilador</a>. Ahora vamos a presentar la última de las modificaciones: el C16C.</p>

<p>La arquitectura de este sistema es la siguiente:</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16c_arquitectura.png" class="liimagelink"><img class="aligncenter size-full wp-image-19099" title="j_computador_c16c_arquitectura" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16c_arquitectura.png" alt="" width="777" height="341" /></a></p>

<p>¡Pero si casi no cambia nada!</p>

<p>Pues sí, cambia un montón. Es solamente un concepto nuevo el que vamos a introducir, pero todo el diseño de los sistemas modernos se basa en él. Vamos a introducir el concepto de <strong>interrupción</strong>.</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>Probablemente no recuerdes ya el programa que hicimos hace un par de capítulos para leer del teclado y actuar en consecuencia&#8230; vamos a pegarlo de nuevo, para que puedas recordarlo.</p>

<table width="810" border="0" cellspacing="0" cellpadding="0"><colgroup> <col width="171" /> <col width="209" /> <col width="430" /> </colgroup>
<tbody>
<tr>
<td width="171" height="21">/TECLA 0&#215;000</td>
<td width="209">LD /TECLADO</td>
<td width="430"></td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /TECLA</td>
<td># Espero a que se pulse una tecla</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /PULSADA</td>
<td># Me guardo la tecla pulsada</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /CONTADOR</td>
<td></td>
</tr>
<tr>
<td height="21">/MULTIPLICACION</td>
<td>LD /CONTADOR</td>
<td># Bucle multiplicador PULSADA*SEGUNDO</td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /FINMULTIPLICACION</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>DEC</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ST /CONTADOR</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>LD /SUMATORIO</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ADD /SEGUNDO</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ST /SUMATORIO</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>BR /MULTIPLICACION</td>
<td></td>
</tr>
<tr>
<td height="21">/FINMULTIPLICACION</td>
<td>LD /SUMATORIO</td>
<td># Al llegar aquí, SUMATORIO=PULSADA*SEGUNDO</td>
</tr>
<tr>
<td height="21">/ESPERA</td>
<td>DEC</td>
<td># Espera durante SUMATORIO ciclos</td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /FINESPERA</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>BR /ESPERA</td>
<td></td>
</tr>
<tr>
<td height="21">/FINESPERA 0&#215;010</td>
<td>LD /PULSADA</td>
<td># Al llegar aquí, han pasado PULSADA segundos</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /PANTALLA1</td>
<td></td>
</tr>
<tr>
<td height="21">/HALT</td>
<td>NOP</td>
<td># Fin</td>
</tr>
<tr>
<td height="21"></td>
<td>BR /HALT</td>
<td></td>
</tr>
<tr>
<td height="21">/SEGUNDO</td>
<td>200</td>
<td># Un segundo</td>
</tr>
<tr>
<td height="21">/PULSADA</td>
<td>0&#215;0000</td>
<td># Donde guardare la tecla pulsada</td>
</tr>
<tr>
<td height="21">/SUMATORIO</td>
<td>0&#215;0000</td>
<td># Donde ire calculando la multiplicacion</td>
</tr>
<tr>
<td height="21">/CONTADOR</td>
<td>0&#215;0000</td>
<td># Donde ire almacenando el contador de la multiplicacion</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
<tr>
<td height="21">/PANTALLA1 0&#215;800</td>
<td>0&#215;0000</td>
<td># Pantalla</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
<tr>
<td height="21">/TECLADO 0&#215;820</td>
<td>0&#215;0000</td>
<td># Teclado</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
</tbody>
</table>

<p>No hace falta que lo recuerdes en detalle. Solo es importante que te fijes en las dos primeras líneas: ¿cómo se lee una tecla pulsada por el usuario?</p>

<p>Lo que hace es mirar a ver si el usuario ha pulsado una tecla, y volver a mirar, y otra vez&#8230; y otra y otra&#8230; así hasta que el usuario efectivamente pulsa una tecla. Esto es lo que se llama <strong>espera activa: en lugar de estar simplemente esperando, está preguntando continuamente si ya está</strong>. La espera activa tiene sus aplicaciones, sobre todo el si el sistema no permite hacer otra cosa, pero como norma general es una chapuza. Date cuenta de que hemos dicho, por ejemplo, que en los sistemas modernos si ejecutamos NOP le estamos diciendo al sistema que no tenemos nada que hacer (por ejemplo para que aplique políticas de ahorro)&#8230; pero aquí no estamos &#8220;haciendo nada&#8221;, sino que estamos haciendo algo: preguntar si ya hay una tecla pulsada.</p>

<p>Es como cuando tu jefe te encarga que hagas algo, y cada cinco minutos pasa por tu sitio y te pregunta &#8220;¿ya has terminado?&#8221;. Y cinco minutos después, otra vez. Y otra, y otra. A la cuarta vez le dices, conteniendo la ira, &#8220;déjame en paz, ya te avisaré yo cuando termine&#8221;. <span style="color: #000000;">Bueno, al menos en este ejemplo el jefe te ha encargado algo. La espera activa es peor aún: es como si cada cinco minutos te pregunta tu jefe &#8220;¿ha llamado algún cliente?&#8221;. &#8220;Déjame en paz, ya te avisaré si llama algún cliente&#8221;&#8230;</span></p>

<p>Bien, pues eso es una interrupción: la CPU no le pregunta al teclado continuamente si tiene algo nuevo, sino que la CPU sigue a su rollo, y el teclado le avisará cuando tenga algo nuevo.</p>

<p>¿Cómo lo hará? Lo hará a través de la línea de IRQ que tiene la CU (IRQ viene de <em>Interruption ReQuest</em>, petición de interrupción). La línea de IRQ funciona por flanco de subida (como los biestables que veíamos hace mucho): si pasa de 0 a 1, es que hay una petición de interrupción del teclado. Esa es la forma en la que el teclado le dice a la CPU que el usuario ha pulsado una tecla.</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16c_teclado.png" class="liimagelink"><img class="aligncenter size-full wp-image-19103" title="j_computador_c16c_teclado" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16c_teclado.png" alt="" width="703" height="690" /></a></p>

<p>&nbsp;</p>

<p>El esquema del teclado es muy sencillo: simplemente se pasan todas las teclas por un AND, de modo que casi siempre valdrá 0. Cuando el usuario pulse una tecla pasará a valer 1 por un breve instante, pero será suficiente, dado que la línea de interrupción funciona por flanco de subida.</p>

<p>Y una vez que ya tenemos la línea de IRQ, ¿cómo funciona? ¿Qué hace la CU con ella? Lo que hace la CU es lo siguiente:</p>

<ul>
    <li>Termina de ejecutar la instrucción que estuviera ejecutando. Recuerda que una instrucción puede tardar más de un ciclo de reloj. Las instrucciones que nosotros hemos hecho en este ordenador son sencillitas, pero hay instrucciones más complejas (en el próximo capítulo veremos más sobre esto).</li>
    <li>Guarda en la pila el &#8220;estado del sistema&#8221;. En nuestro caso el estado del sistema son los dos registros: PC y AC. Vale, pues los guarda en la pila.</li>
    <li>Salta a la posición 0&#215;100 y ejecuta lo que haya allí. Es decir, pone en PC el número 0&#215;100 y continúa.</li>
</ul>

<p>¿Te das cuenta de que es algo parecido a las subrutinas? Es una forma un poco especial de subrutina, pero vaya&#8230; se parece, en cierto modo. Así que habrá algún tipo de forma de retorno, ¿no? Sí, efectivamente: se define una nueva instrucción llamada RTI (<em>ReTurn from Interruption</em>, retorno de interrupción) que hace básicamente lo contrario: saca de la pila el valor de AC que habíamos guardado y lo restaura; saca de la pila el valor de PC que habíamos guardado y lo restaura. Como antes, no vamos a ver en detalle cómo se hacen estas dos operaciones, pero a estas alturas espero que no te resulte completamente mágico el cómo lo hace la CU.</p>

<p>Entonces, ¿cómo quedaría nuestro programa?</p>

<table width="810" border="0" cellspacing="0" cellpadding="0"><colgroup> <col width="171" /> <col width="209" /> <col width="430" /> </colgroup>
<tbody>
<tr>
<td width="171" height="21">/HALT</td>
<td width="209">NOP</td>
<td width="430"># Fin</td>
</tr>
<tr>
<td height="21"></td>
<td>BR /HALT</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
<tr>
<td height="21">/TECLA 0&#215;100</td>
<td>LD /TECLADO</td>
<td># Leo la tecla que me han pulsado</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /PULSADA</td>
<td># Me guardo la tecla pulsada</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /CONTADOR</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>CLR</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ST /SUMATORIO</td>
<td></td>
</tr>
<tr>
<td height="21">/MULTIPLICACION</td>
<td>LD /CONTADOR</td>
<td># Bucle multiplicador PULSADA*SEGUNDO</td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /FINMULTIPLICACION</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>DEC</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ST /CONTADOR</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>LD /SUMATORIO</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ADD /SEGUNDO</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ST /SUMATORIO</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>BR /MULTIPLICACION</td>
<td></td>
</tr>
<tr>
<td height="21">/FINMULTIPLICACION</td>
<td>LD /SUMATORIO</td>
<td># Al llegar aquí, SUMATORIO=PULSADA*SEGUNDO</td>
</tr>
<tr>
<td height="21">/ESPERA</td>
<td>DEC</td>
<td># Espera durante SUMATORIO ciclos</td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /FINESPERA</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;110</td>
<td>BR /ESPERA</td>
<td></td>
</tr>
<tr>
<td height="21">/FINESPERA</td>
<td>LD /PULSADA</td>
<td># Al llegar aquí, han pasado PULSADA segundos</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /PANTALLA1</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>RTI</td>
<td></td>
</tr>
<tr>
<td height="21">/SEGUNDO</td>
<td>200</td>
<td># Un segundo</td>
</tr>
<tr>
<td height="21">/PULSADA</td>
<td>0&#215;0000</td>
<td># Donde guardare la tecla pulsada</td>
</tr>
<tr>
<td height="21">/SUMATORIO</td>
<td>0&#215;0000</td>
<td># Donde ire calculando la multiplicacion</td>
</tr>
<tr>
<td height="21">/CONTADOR</td>
<td>0&#215;0000</td>
<td># Donde ire almacenando el contador de la multiplicacion</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
<tr>
<td height="21">/PANTALLA1 0&#215;800</td>
<td>0&#215;0000</td>
<td># Pantalla</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
<tr>
<td height="21">/TECLADO 0&#215;820</td>
<td>0&#215;0000</td>
<td># Teclado</td>
</tr>
</tbody>
</table>

<p>La mayor parte del programa es el mismo, pero las diferencias son brutales. Date cuenta de que, nada más empezar, en las líneas 0&#215;000 y 0&#215;001, simplemente ¡entra en el bucle de <em>fin</em>! ¡Es decir, ya se queda sin hace nada! La diferencia ahora es que a partir de la línea 0&#215;100 hay cosas. La posición 0&#215;100 es a donde saltará la ejecución cuando el usuario pulse una tecla&#8230; y a partir de ahí, es exactamente igual que en el programa anterior: multiplica, espera durante unos segundos y escribe la tecla pulsada en pantalla&#8230; y después retorna de la interrupción, el RTI de la línea 0&#215;111. Es decir, vuelve al bucle a no hacer nada (es decir, hasta que el usuario pulse otra tecla, en cuyo momento volverá a saltar la interrupción y vuelta a empezar).</p>

<p>Puede parecer que es una tontería, y que no ha cambiado mucho&#8230; ahora intentaré convencerte de lo contrario. Pero primero, asegúrate de entenderlo, incluso aunque creas que el concepto no es importante. La CPU puede estar ejecutando cualquier cosa: cuando se levante una interrupción a través de la línea IRQ, ejecutará esa especie de subrutina y luego seguirá por donde iba.</p>

<p>La potencia de este método viene del hecho de que en los ordenadores reales no existe una entrada de interrupción, sino muchas. Vamos a poner unos cuantos ejemplos, pero no te fijes en el orden para ver su importancia: las del final son muy muy importantes también.</p>

<ul>
    <li>Cuando el usuario pulsa una tecla.</li>
    <li>Cuando la pantalla ha terminado de escribir lo que le han pedido.</li>
    <li>Cuando entra sonido a través del micrófono de la tarjeta de sonido.</li>
    <li>Cuando ha terminado de reproducir (a través de la tarjeta de sonido) lo que le hemos pedido que reproduzca.</li>
    <li>Cuando entran datos a través de la tarjeta de red.</li>
    <li>Cuando la tarjeta de red ha terminado de enviar los datos que le habíamos pedido que enviara.</li>
    <li>Cuando existe una división por cero. Sabes que dividir <em>cualquiercosa/0</em> es un error&#8230; pues bien, eso levanta una interrupción que viene de la ALU.</li>
    <li>Cuando se intenta acceder a una zona de memoria que no existe o sobre la que no tenemos permiso (veremos más sobre esto más adelante).</li>
    <li>Cuando lo pide el programa. Suele haber una (o varias) instrucciones que generan una interrupción. También veremos esto más adelante. Esto es lo que se llama una &#8220;interrupción por software&#8221;.</li>
    <li>Periódicamente, según un reloj. Por ejemplo, cada 1ms.</li>
    <li>Cuando se prevé un fallo de alimentación.</li>
    <li>Cuando ha terminado de escribir en disco lo que le hemos pedido.</li>
</ul>

<p>Prácticamente cualquier cosa importante que pueda ocurrir en un ordenador hoy en día genera una interrupción.</p>

<p>La gracia de esas interrupciones es que pueden ocurrir en cualquier momento&#8230; ¡incluso mientras estoy ejecutando otra interrupción!<sup>[<a href="https://eltamiz.com/elcedazo/2014/03/22/computador-magico-xxvii-ordenador-c16c-interrupciones/#footnote_0_19097" id="identifier_0_19097" class="footnote-link footnote-identifier-link" title="No obstante, suele haber alg&uacute;n mecanismo de priorizaci&oacute;n, porque algunas de las interrupciones son muy importantes y no se deben interrumpir. Por ejemplo, se pueden numerar y una interrupci&oacute;n solo puede ser interrumpida por otra interrupci&oacute;n de n&uacute;mero menor.">1</a>]</sup></p>

<p>Volveremos sobre esto más adelante, cuando veamos los sistemas multiproceso, pero los sistemas operativos modernos hacen absolutamente todo su trabajo en base a interrupciones. Un sistema operativo moderno, una vez que se ha inicializado, simplemente se queda en un bucle sin hacer nada hasta que salta una interrupción. Lo veremos más adelante con más detalle, de momento céntrate solo en conocer el concepto de interrupción y cómo opera.</p>

<p>En el próximo capítulo terminaremos este nivel de la máquina nombrando alguna de las diferencias más importantes entre los sistemas reales y estos ejemplos de máquinas académicas.</p>

<p>&nbsp;</p>
<ol class="footnotes"><li id="footnote_0_19097" class="footnote">No obstante, suele haber algún mecanismo de priorización, porque algunas de las interrupciones son muy importantes y no se deben interrumpir. Por ejemplo, se pueden numerar y una interrupción solo puede ser interrumpida por otra interrupción de número menor.</li></ol>]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2014/03/22/computador-magico-xxvii-ordenador-c16c-interrupciones/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<item>
		<title>Computador mágico XXVI &#8211; El compilador</title>
		<link>https://eltamiz.com/elcedazo/2014/02/08/computador-magico-xxvi-el-compilador/</link>
		<comments>https://eltamiz.com/elcedazo/2014/02/08/computador-magico-xxvi-el-compilador/#comments</comments>
		<pubDate>Sat, 08 Feb 2014 11:44:19 +0000</pubDate>
		<dc:creator>J</dc:creator>
				<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[J]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=19110</guid>
		<description><![CDATA[La serie &#8220;El computador mágico&#8221; está disponible también en forma de libro. En el último capítulo de esta serie presentamos el ordenador C16B y el concepto de subrutina, y escribimos un programa que calculaba el factorial de un número. Pero vimos que el programa empezaba a ser demasiado grande y que nos iba resultando útil describir su [...]]]></description>
			<content:encoded><![CDATA[<div align="left">
<table class="bookBox" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<td valign="center">
<p style="text-align: center; margin-top: 1px; margin-bottom: 1px; margin-left: 1px;" align="center"><a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liimagelink"><img class="aligncenter size-full wp-image-18513" title="Computador mágico" src="http://eltamiz.com/elcedazo/wp-content/uploads/2016/01/ComputadorMagicoDigest_v21_cover_v1_front2.png" alt="" width="90" height="128" /></a></p>
</td>
<td valign="center">

<p style="text-align: left;" align="center">
La serie &#8220;El computador mágico&#8221; está disponible también <a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liinternal">en forma de libro</a>.
</p>
</td>
</tr>
</tbody>
</table>
</div>

<p>En el <a href="/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/" title="Computador mágico XXV – Ordenador C16B: subrutinas" target="_blank" class="liinternal">último capítulo</a> de esta <a href="/elcedazo/series/computador-magico/" title="Computador mágico" target="_blank" class="liinternal">serie</a> presentamos el ordenador C16B y el concepto de subrutina, y escribimos un programa que calculaba el factorial de un número. Pero vimos que el programa empezaba a ser demasiado grande y que nos iba resultando útil describir su funcionamiento con algún tipo de pseudolenguaje, así que describíamos nuestro programa tal que así:
<pre>numero = 6
resultado = 1
mientras (numero != 0) {
  resultado = multiplicar(resultado,numero)
  numero = numero -1
}
&#35; El resultado está en resultado
subrutina multiplicar(p, q) {
  res = 0
  mientras (p != 0) {
    p = p -1
    res = res + q
  }
  devolver res
}</pre>
&nbsp;</p>

<p>Supongo que te resulta mucho más sencillo de entender, ¿verdad?</p>

<p>&nbsp;</p>

<p>Haz ahora un ejercicio: en el <a href="/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/" title="Computador mágico XXV – Ordenador C16B: subrutinas" target="_blank" class="liinternal">capítulo anterior</a> lo que hicimos fue escribir el programa en ensamblador y luego describirlo de esta forma un poco más abstracta. Pero&#8230; ¿serías capaz de hacer lo contrario? Es decir, si te doy el programa descrito en esta forma abstracta, ¿serías capaz de convertirlo en las instrucciones de ensamblador correspondientes?</p>

<p>Espero que la respuesta sea un <em>sí, claro</em>.</p>

<p>Pues eso es lo que hace un compilador: primero nos inventamos un lenguaje que sea más cercano al natural (no te sorprenderá que se base en el inglés) y luego el compilador traduce eso a código máquina. Por ejemplo, si quisiéramos escribir ese mismo programa en (algo parecido a) C,<sup>[<a href="https://eltamiz.com/elcedazo/2014/02/08/computador-magico-xxvi-el-compilador/#footnote_0_19110" id="identifier_0_19110" class="footnote-link footnote-identifier-link" title="C es un lenguaje de programaci&oacute;n, probablemente el m&aacute;s famoso de todos.">1</a>]</sup> haríamos lo siguiente:
<pre>int multiplicar(int p, int q) {
  int res = 0;
  while (p != 0) {
    p = p - 1;
    res = res + q;
  }
  return res;
}
int numero = 6;
int resultado = 1;
while (numero != 0) {
  resultado = multiplicar(resultado, numero);
  numero = numero -1;
}
// Al llegar aqui, resultado ya tiene el factorial</pre>
&nbsp;</p>

<p>Supongo que, a poco inglés que sepas, eres capaz de deducir qué es lo que hace este código en C.</p>

<p>Pues bien, con esto hemos inventado los lenguajes de programación.</p>

<p>El programa, escrito en este lenguaje de programación, se llama &#8220;código fuente&#8221;. Lo que se carga en la memoria del ordenador para ser ejecutado se llama &#8220;código objeto&#8221; o &#8220;binario&#8221; u &#8220;objeto&#8221; u otras cosas así. El proceso de convertir el código fuente en el código objeto se llama &#8220;compilar&#8221;.</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_compilador_diagrama.png" class="liimagelink"><img class="aligncenter size-full wp-image-19128" title="j_computador_compilador_diagrama" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_compilador_diagrama.png" alt="" width="555" height="95" /></a></p>

<p>&nbsp;</p>

<p>¿Podríamos hacer un programa que tome el código fuente y genere automáticamente el código binario? Sí, claro que podemos, no es más que una traducción de un formato a otro. No solo eso, sino que, además, dada la complejidad de los ordenadores actuales, el nivel de abstracción de los lenguajes de programación modernos y la potencia de los compiladores de hoy en día, el código binario que generan los compiladores es a menudo mejor que lo que podría lograr un ser humano típico escribiendo directamente el programa en ensamblador. No vamos a ver nada sobre teoría de compiladores, supongo que entre lo que hemos visto antes y estos párrafos eres capaz de entender que hacer esa traducción, esa compilación, es posible.</p>

<p>Lo que hemos visto es un lenguaje de programación, el lenguaje C, que es de muy bajo nivel: se dice que un lenguaje de programación es de más bajo nivel cuanto más cercano al código ensamblador está en su nivel de abstracción. C es un lenguaje de muy bajo nivel (hasta el punto de que a menudo se le llama, peyorativamente, &#8220;ensamblador de alto nivel&#8221;, para indicar que es &#8220;poco más que el ensamblador&#8221;).<sup>[<a href="https://eltamiz.com/elcedazo/2014/02/08/computador-magico-xxvi-el-compilador/#footnote_1_19110" id="identifier_1_19110" class="footnote-link footnote-identifier-link" title="Ojo: &amp;#8220;bajo nivel&amp;#8221; no significa que sea malo. Hace referencia a su nivel de abstracci&oacute;n, no a si es bueno o malo.">2</a>]</sup> Otros lenguajes también de bajo nivel son Pascal o Fortran.</p>

<p>Fíjate en que en estos lenguajes se definen estructuras de datos y funciones (lo que nosotros hemos llamado subrutinas) que se van llamando unas a otras astutatemente para operar con dichos datos&#8230; y poco más. Esto es lo que se llama <strong>programación procedural</strong> o <strong>programación imperativa</strong>.<sup>[<a href="https://eltamiz.com/elcedazo/2014/02/08/computador-magico-xxvi-el-compilador/#footnote_2_19110" id="identifier_2_19110" class="footnote-link footnote-identifier-link" title="Su definici&oacute;n formal es mucho m&aacute;s farragosa, algo as&iacute; como &amp;#8220;el paradigma que se basa en definir un estado y cambios sobre dicho estado&amp;#8221;&amp;#8230; que en el fondo no es m&aacute;s que lo que nosotros sabemos que es un circuito secuencial.">3</a>]</sup></p>

<p>Pero a la gente rápidamente se le ocurrió que podía dar un nivel más de abstracción, inventando otros paradigmas de programación. Así, por ejemplo, se inventó la <strong>programación orientada a objetos</strong>. En ella se definen <em>objetos</em>, que tienen una serie de <em>propiedades</em>  y de <em>operaciones</em>. Puede parecer que es muy parecido a la programación imperativa, y es que de hecho está basada en ella. Su mayor potencia radica en que los objetos &#8220;heredan&#8221; cosas unos de otros. Así por ejemplo, podemos tener un objeto de tipo <em>Vehículo</em>, que tiene una propiedad que es la <em>Velocidad</em> y una operación que es <em>Acelerar</em>. Podemos también tener un objeto de tipo <em>Coche</em>, que es &#8220;hijo&#8221; del tipo <em>Vehículo</em>. Como es hijo de <em>Vehículo</em>, tiene todas sus propiedades y operaciones, pero puede también definir propiedades y operaciones nuevas. Por ejemplo, puede tener la propiedad <em>NumeroDeRuedas</em> y la operación <em>CambiarRueda</em>&#8230; pero ojo, que sigue teniendo la propiedad <em>Velocidad</em> y la operación <em>Acelerar</em>. O también podemos tener otro tipo, el tipo <em>Barco</em>, que también es hijo de <em>Vehículo</em>, con un par de propiedades nuevas <em>Eslora</em> y <em>NumeroDeCubiertas</em>, y con la operación <em>Atracar</em>. Como <em>Barco</em> es hijo de <em>Vehículo</em>, tiene la propiedad <em>Velocidad</em> y la operación <em>Acelerar</em>, pero como no tiene nada que ver con <em>Coche</em> no tiene ninguna operación llamada <em>CambiarRueda</em>.<sup>[<a href="https://eltamiz.com/elcedazo/2014/02/08/computador-magico-xxvi-el-compilador/#footnote_3_19110" id="identifier_3_19110" class="footnote-link footnote-identifier-link" title="Bueno, es su &amp;#8220;hermano&amp;#8221;, pero en este paradigma eso no importa.">4</a>]</sup> En fin, es un ejemplo muy tonto, pero combinando adecuadamente esos objetos y operaciones se pueden hacer cosas muy complejas.</p>

<p>La programación orientada a objetos probablemente es hoy en día el paradigma más extendido, en lenguajes como C++, Java, Objetive C, C#, PHP&#8230;<sup>[<a href="https://eltamiz.com/elcedazo/2014/02/08/computador-magico-xxvi-el-compilador/#footnote_4_19110" id="identifier_4_19110" class="footnote-link footnote-identifier-link" title="Estoy obviando que muchos de estos lenguajes son interpretados, o se ejecutan sobre m&aacute;quinas virtuales&amp;#8230; si no sabes de qu&eacute; hablo, no te preocupes, no es necesario.">5</a>]</sup> Existen otros paradigmas, pero, y espero que sus partidarios no se me tiren al cuello, no están tan extendidos: programación funcional, programación lógica, programación declarativa&#8230; sus partidarios sostienen que SUSTITUYA-AQUÍ-SU-PARADIGMA-FAVORITO le dice al ordenador qué tiene que hacer, mientras que la programación imperativa (y su hija, la programación orientada a objetos) le dice al ordenador cómo tiene que hacerlo, y que por eso SUSTITUYA-AQUÍ-SU-PARADIGMA-FAVORITO es mejor. Ni que decir tiene que algo de razón lleva, pero limitar la discusión a &#8220;X es mejor que Y&#8221; es muy superficial.</p>

<p>No vamos a entrar más en detalle en teoría de lenguajes, pues llevaría para un libro entero. Este capítulo, que ha sido ligerito en comparación de a lo que estamos habituados, servirá para que veas que en el futuro veremos muchas cosas de una forma más abstracta, sin escribir tanto ensamblador. En el próximo capítulo veremos la última de las versiones de C16, el C16C.</p>

<p>&nbsp;</p>
<ol class="footnotes"><li id="footnote_0_19110" class="footnote">C es un lenguaje de programación, probablemente el más famoso de todos.</li><li id="footnote_1_19110" class="footnote">Ojo: &#8220;bajo nivel&#8221; no significa que sea malo. Hace referencia a su nivel de abstracción, no a si es bueno o malo.</li><li id="footnote_2_19110" class="footnote">Su definición formal es mucho más farragosa, algo así como &#8220;el paradigma que se basa en definir un estado y cambios sobre dicho estado&#8221;&#8230; que en el fondo no es más que lo que nosotros sabemos que es un circuito secuencial.</li><li id="footnote_3_19110" class="footnote">Bueno, es su &#8220;hermano&#8221;, pero en este paradigma eso no importa.</li><li id="footnote_4_19110" class="footnote">Estoy obviando que muchos de estos lenguajes son interpretados, o se ejecutan sobre máquinas virtuales&#8230; si no sabes de qué hablo, no te preocupes, no es necesario.</li></ol>]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2014/02/08/computador-magico-xxvi-el-compilador/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<item>
		<title>Computación Cuantica II &#8211; El qubit</title>
		<link>https://eltamiz.com/elcedazo/2014/01/26/computacion-cuantica-ii-el-qubit/</link>
		<comments>https://eltamiz.com/elcedazo/2014/01/26/computacion-cuantica-ii-el-qubit/#comments</comments>
		<pubDate>Sun, 26 Jan 2014 09:32:40 +0000</pubDate>
		<dc:creator>Carlo</dc:creator>
				<category><![CDATA[Carlo]]></category>
		<category><![CDATA[Computación cuántica]]></category>
		<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=27891</guid>
		<description><![CDATA[Vamos a comenzar de verdad la serie sobre computación cuántica, y como habíamos prometido, vamos a hablar del qubit. El qubit es el análogo en CC al bit de computación clásica, pero veremos que es un poco más complicado. Y por eso vamos a ir por partes. Comencemos recordando lo que es un bit. Un [...]]]></description>
			<content:encoded><![CDATA[<p>Vamos a comenzar <em>de verdad</em> la serie sobre computación cuántica, y <a href="http://eltamiz.com/elcedazo/2014/01/04/computacion-cuantica-i-introduccion/" target="_blank" class="liinternal">como habíamos prometido</a>, vamos a hablar del <em>qubit</em>. El qubit es el análogo en CC al bit de computación clásica, pero veremos que es un poco más complicado. Y por eso vamos a ir por partes. Comencemos recordando lo que es un bit.</p>

<p>Un bit es un dígito en el sistema binario, y es el elemento básico de los circuitos eléctricos digitales y, por tanto, de los ordenadores. No voy a recordar lo que es el sistema binario porque <a href="http://eltamiz.com/elcedazo/2012/10/14/computador-magico-viii-representacion-binaria-i-naturales/" class="liinternal">ya se ha explicado</a>; baste con recordar que cualquier número lo podemos traducir a binario, 13 en decimal es 1101 en binario, y cada uno de los unos o ceros que forman el número es un bit. Eso en la parte púramente matemática; en electrónica representamos cada bit como un voltaje alto o bajo, o como una bombilla encendida, <img class="alignnone" src="http://upload.wikimedia.org/wikipedia/commons/6/60/Bulbgraph.png" alt="Bit 1" width="44" height="54" />, que sería un 1, o una bombilla apagada, <img class="alignnone" src="http://upload.wikimedia.org/wikipedia/commons/4/49/Bulbgraph_Off.png" alt="Bit 0" width="44" height="54" />, que sería un cero.</p>

<p>Hasta aquí la parte clásica; para introducir ahora el concepto de qubit tenemos que tener en cuenta, si recuerdas la serie <a href="http://eltamiz.com/2008/11/10/cuantica-sin-formulas-estados-cuanticos/" class="liinternal">Cuántica sin Fórmulas</a>, que al llegar al nivel cuántico las cosas no suelen estar encendidas ni apagadas &#8220;de verdad&#8221;, sino que están en un <em>estado</em> que es una especie de mezcla de ambas cosas. Eso es un qubit: no tenemos la bombilla encendida ni apagada, sino que está &#8220;en otro estado&#8221; que no es ni encendido, ni apagado. Recuerda, esto es muy importante, porque no significa que la bombilla esté encendida a medias, ni rota, ni nada similar: está <em>a la vez</em> encendida y apagada.</p>

<p>¿Cómo vamos a representar esto? Vamos a usar la llamada <a href="http://es.wikipedia.org/wiki/Notaci%C3%B3n_bra-ket" rel="nofollow" class="liwikipedia">notación bra-ket</a>, que Pedro ya nos introdujo en el link que enlacé antes: ¡repásatelo! Vamos a tener dos posibles kets, que son autoestados de la bombilla: el ket |<img src="http://upload.wikimedia.org/wikipedia/commons/6/60/Bulbgraph.png" alt="Bit 1" width="44" height="54" />&gt;, que representa una bombilla encendida, y el ket |<img src="http://upload.wikimedia.org/wikipedia/commons/4/49/Bulbgraph_Off.png" alt="Bit 0" width="44" height="54" />&gt;, que representa una bombilla apagada. Pues bien, el estado general de nuestro qubit va a ser lo que se llama una <em>superposición</em> de los dos estados, a·|<img src="http://upload.wikimedia.org/wikipedia/commons/4/49/Bulbgraph_Off.png" alt="Bit 0" width="44" height="54" />&gt;+b·|<img src="http://upload.wikimedia.org/wikipedia/commons/6/60/Bulbgraph.png" alt="Bit 1" width="44" height="54" />&gt;, donde a y b son <em>números complejos</em>.</p>

<p>Varios apuntes aquí: el primero, recuerda que esto no significa que esté medio encendida ni nada similar, sino que está <strong>a la vez encendida y apagada</strong>, en un cierto sentido. El segundo, voy a intentar evitar usar números complejos porque sé que son mucho más liosos; casi siempre podré conseguirlo y usar <em>números reales</em>, aunque cuando veamos algunas puertas será necesario meternos un momento en ellos. Si te parecen muy difíciles los números complejos sáltate ese momentito y ya está. El tercero, a y b <strong><em>no son números independientes</em></strong> (muy remarcado porque es muy importante). Existe una cosa que se llama normalización, que es básica para poder calcular probabilidades y demás, y nos obliga a que ambos números sigan una relación, |a|²+|b|²=1, que significa que el cuadrado del módulo de a más el cuadrado del módulo de b tienen que sumar 1. Si, como hemos dicho, nos restringimos a números reales, se puede escribir esto más fácilmente: a²+b²=1. De aquí podemos ver que tanto a como b tienen que ser números que estén entre -1 y 1, y que cuanto más <em>lejos del cero</em> esté uno, más <em>cerca del cero</em> estará el otro.</p>

<p>Hasta aquí las matemáticas. ¿Qué quiere decir esto? Pues quiere decir que un qubit no vamos a saber si es un 1 o un 0 mientras no lo miremos. Y no sólo es que no lo sepamos, es que hasta entonces sólo <em>hay una probabilidad de que sea 1 y una probabilidad de que sea 0, pero el qubit <strong>no es ni cero ni uno</strong></em>. Pero al mirarlo tendremos que ver necesariamente un 1 o un 0, con una cierta probabilidad. ¿Y qué probabilidad? Pues precisamente a² de que sea 0, es decir, de que la bombilla esté apagada, y b² de que sea 1, es decir, de que la bombilla esté encendida.</p>

<p>Un ejemplo (y permitidme que cambie los nombres a los kets: ahora al ket |<img src="http://upload.wikimedia.org/wikipedia/commons/6/60/Bulbgraph.png" alt="Bit 1" width="44" height="54" />&gt; le llamaré |1&gt; y al ket |<img src="http://upload.wikimedia.org/wikipedia/commons/4/49/Bulbgraph_Off.png" alt="Bit 0" width="44" height="54" />&gt; le llamaré |0&gt;, pero podéis seguir pensando en bombillas al verlos, si así os resulta más fácil). Supongamos que nuestro qubit está en el estado 0.8·|0&gt;+0.6·|1&gt;. Primero vamos a comprobar que cumple la relación que pusimos arriba: (0.8)²+(0.6)²=0.64+0.36=1, por lo que sí, la cumple. Esto nos quiere decir que es un estado válido, un qubit <em>puede</em> estar en este estado. ¿Qué probabilidades hay de que al mirar el qubit sea 1, y qué probabilidades hay de que sea 0? Pues la probabilidad de que sea 0 es simplemente (0.8)², es decir, 0.64, es decir, un 64%. Y la probabilidad de que sea 1 es (0.6)², es decir, 0.36, es decir, un 36%. ¡Anda, las probabilidades suman 1! ¡Qué casualidad! Pues no, no lo es, para eso precisamente era la normalización. Al normalizar, las probabilidades salen así de fácil.<em></em></p>

<p>Una cosa <em>fastidiosa</em> y a la vez <em>totalmente necesaria</em> para la CC es que cuando miramos ese qubit, y tenemos unas probabilidades de ver un 0 o de ver un 1, no solamente vemos el qubit: lo cambiamos. Y lo cambiamos a un nuevo estado perfectamente definido y perfectamente no cuántico. Si miramos y vemos un 0, <em>ahora el estado será |0&gt;</em>. Si miramos y vemos un 1, <em>ahora el estado será 1</em>. Y se nos &#8220;borrará&#8221; toda la información extra (el a y el b, el 0.8 y el 0.6) que teníamos antes. Esa información desaparece totalmente, y no hay manera de recuperarla. Cuando nosotros queramos medir el qubit, entonces eso estará bien, porque es lo que queríamos (y veremos que todos los algoritmos cuánticos miden qubits al final). Pero si por el contrario &#8220;medimos sin querer&#8221; en mitad de un cálculo&#8230; perderemos la información y el cálculo saldrá mal. Hay muchas formas de &#8220;medir sin querer&#8221;, y las comentaré cuando lleguemos a cómo se construye un qubit en la realidad &#8211; probablemente, cerca del final de la serie.</p>

<p>Ahora los más avispados estaréis preguntándoos: ¿cómo sabemos el estado del qubit, ese 0.8·|0&gt;+0.6·|1&gt;, si no lo hemos mirado? Pues es muy simple: en general, <em>no lo sabemos</em>. Pero la Naturaleza, de una forma que no entendemos completamente, sí lo sabrá, y eso a nosotros nos basta. Nosotros simplemente comenzaremos con un estado |0&gt; o |1&gt;, que sabemos ponerlos con mucha facilidad (¡mirando!) y aplicaremos puertas lógicas cuánticas que cambiarán el estado. En principio podemos ir calculando qué cambios hace exactamente, pero la gracia de la computación cuántica es que no lo necesitaremos: la Naturaleza lo hará por nosotros y nos facilitará mucho el trabajo.</p>

<p>Y hasta aquí lo que es un qubit. Cuando hay más de un qubit las cosas cambian, pero antes de meternos en eso, en la próxima entrada veremos las puertas lógicas de un qubit.</p>
]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2014/01/26/computacion-cuantica-ii-el-qubit/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<item>
		<title>Computador mágico XXV &#8211; Ordenador C16B: subrutinas</title>
		<link>https://eltamiz.com/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/</link>
		<comments>https://eltamiz.com/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/#comments</comments>
		<pubDate>Sun, 01 Dec 2013 10:20:17 +0000</pubDate>
		<dc:creator>J</dc:creator>
				<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[J]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=19066</guid>
		<description><![CDATA[La serie &#8220;El computador mágico&#8221; está disponible también en forma de libro. En el último capítulo de esta serie veíamos un programa relativamente complejo que permitía temporizar la salida hacia la pantalla dependiendo de la tecla que habíamos pulsado&#8230; pero decíamos que había algunas cosas que eran un poco chapuceras. No eran culpa del diseño [...]]]></description>
			<content:encoded><![CDATA[<div align="left">
<table class="bookBox" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<td valign="center">
<p style="text-align: center; margin-top: 1px; margin-bottom: 1px; margin-left: 1px;" align="center"><a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liimagelink"><img class="aligncenter size-full wp-image-18513" title="Computador mágico" src="http://eltamiz.com/elcedazo/wp-content/uploads/2016/01/ComputadorMagicoDigest_v21_cover_v1_front2.png" alt="" width="90" height="128" /></a></p>
</td>
<td valign="center">

<p style="text-align: left;" align="center">
La serie &#8220;El computador mágico&#8221; está disponible también <a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liinternal">en forma de libro</a>.
</p>
</td>
</tr>
</tbody>
</table>
</div>

<p>En el <a href="http://eltamiz.com/elcedazo/2013/11/03/computador-magico-xxiv-ordenador-c16a-iv-temporizador/" target="_blank" class="liinternal">último capítulo</a> de <a href="http://eltamiz.com/elcedazo/series/computador-magico/" target="_blank" class="liinternal">esta serie</a> veíamos un programa relativamente complejo que permitía temporizar la salida hacia la pantalla dependiendo de la tecla que habíamos pulsado&#8230; pero decíamos que había algunas cosas que eran un poco chapuceras. No eran culpa del diseño del programa&#8230; es que con ese ordenador no se podía hacer mucho más. Así que vamos a mejorar el ordenador C16A con una pila, y lo vamos a llamar C16B.</p>

<p>La arquitectura de nuestro nuevo ordenador será la siguiente:</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16b_arquitectura.png" class="liimagelink"><img class="aligncenter size-full wp-image-19067" title="j_computador_c16b_arquitectura" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16b_arquitectura.png" alt="" width="779" height="340" /></a></p>

<p>&nbsp;</p>

<p>Supongo que te has dado cuenta de que, arquitecturalmente, hay poca diferencia: existe un nuevo registro que se llama SP (del inglés <em>Stack Pointer</em>, puntero de la pila). Como probablemente no sabes lo que es una pila, vamos a verla primero a nivel teórico y luego vemos su uso en el C16B.</p>

<p>Una pila almacena &#8220;cosas&#8221; (en nuestro ejemplo almacenará números enteros de 16 bits), y tiene dos operaciones: PUSH y POP. En este contexto se suelen traducir como &#8220;meter&#8221; y &#8220;sacar&#8221; respectivamente. O también &#8220;poner&#8221; y &#8220;quitar&#8221;. O mejor dicho: no se traducen; todo el mundo usa los términos en inglés. La gracia es que la pila es un sistema LIFO (<em>Last In First Out</em>, el último en entrar es el primero en salir): si vas metiendo uno o más elementos en la pila, cuando saques, sacarás el último que metiste. Podemos imaginárnoslo como una caja profunda o un barril en el que metemos artículos relativamente voluminosos: metemos el Primero, y se va al fondo; metemos el Segundo, y se queda sobre el Primero; metemos un Tercero, y se queda sobre el Segundo; si ahora sacamos, sacaremos el Tercero; si volvemos a sacar, sacaremos el Segundo. Quizá el siguiente dibujo te ayude a entenderlo:</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16b_pila1.png" class="liimagelink"><img class="aligncenter size-full wp-image-19080" title="j_computador_c16b_pila" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16b_pila1.png" alt="" width="693" height="686" /></a></p>

<p>Date cuenta de que conceptualmente PUSH tiene un &#8220;parámetro&#8221;. Es decir, cuando hacemos PUSH hay que decir <em>PUSH de ¿qué?</em>. O sea, ¿qué es lo que hay que meter en la pila? En cambio, cuando hacemos POP, lo que obtenemos es lo que haya en lo alto de la pila,<sup>[<a href="https://eltamiz.com/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/#footnote_0_19066" id="identifier_0_19066" class="footnote-link footnote-identifier-link" title="T&eacute;cnicamente, en espa&ntilde;ol se denomina la &amp;#8220;cabeza de la pila&amp;#8221;, y sacar un elemento de la pila con un POP, lo llamamos &amp;#8220;descabezar&amp;#8221; la pila.">1</a>]</sup> no tenemos que decir qué es lo que queremos sacar&#8230; lo que sí que hay que decir es qué hacemos con eso que hemos sacado.</p>

<p>Vamos a implementar entonces nuestra pila al final de la memoria principal. Cuando arranca el sistema, hacemos que el registro SP contenga la dirección 0x7FF. Cuando nos pidan meter algo en la pila (PUSH), lo que haremos es escribirlo en la posición de la memoria donde diga SP, y luego restar 1 de SP. Cuando lo que nos pidan sea sacar de la pila (POP), recuperaremos lo que haya en la dirección siguiente a la que apunte SP, y luego sumaremos 1 a SP. A ver si el siguiente dibujo te ayuda a entenderlo:</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16b_SP.png" class="liimagelink"><img class="aligncenter size-full wp-image-19071" title="j_computador_c16b_SP" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16b_SP.png" alt="" width="265" height="651" /></a></p>

<p>¿Lo ves? Empieza apuntando al final de la memoria. Cuando hacemos la operación PUSH 1234, se introduce ese 1234 al final, y se resta 1 a SP. Luego se hace PUSH de otro número: el 9876. Después se hace POP, de modo que el 9876 sale de la pila y SP apunta una posición más abajo de nuevo, en este caso al 1234. Fácil, ¿verdad?</p>

<p>Bueno, pues vamos a añadir cuatro instrucciones más a nuestro ordenador. Recordarás que habíamos reservado 4 bits para las instrucciones (16 combinaciones posibles), pero solo teníamos 8 instrucciones usadas. Vamos a añadir otras 4:</p>

<table width="683" border="1" cellspacing="0" cellpadding="0"><colgroup> <col width="125" /> <col width="558" /> </colgroup>
<tbody>
<tr>
<td width="125" height="21"><strong>Mnemotécnico</strong></td>
<td width="558"><strong>¿Qué hace?</strong></td>
</tr>
<tr>
<td height="43">NOP</td>
<td width="558"><em>No Operation</em>. Operación que no hace nada.</td>
</tr>
<tr>
<td height="43">ST &lt;addr&gt;</td>
<td width="558">Almacena (del inglés <em>store</em>) el contenido del acumulador en la posición de memoria &lt;addr&gt;. addr es del inglés address, dirección.</td>
</tr>
<tr>
<td height="43">LD &lt;addr&gt;</td>
<td width="558">Carga (del inglés <em>load</em>) en el acumulador el contenido de la posición de memoria &lt;addr&gt;.</td>
</tr>
<tr>
<td height="43">ADD &lt;addr&gt;</td>
<td width="558">Suma (del inglés <em>add</em>) el contenido del acumulador con el contenido de la posición de memoria &lt;addr&gt;, y deja el resultado en el acumulador.</td>
</tr>
<tr>
<td height="43">BR &lt;addr&gt;</td>
<td width="558">Salta (del inglés <em>branch</em>) la ejecución a la posición &lt;addr&gt;. E decir, en vez de continuar ejecutando en PC+1, continúa ejecutando en la posición de memoria &lt;addr&gt;</td>
</tr>
<tr>
<td height="43">BZ &lt;addr&gt;</td>
<td width="558">Del inglés <em>branch if zero</em>, salta si es cero. Es decir, lo mismo que BR, pero solo si el contenido del acumulador es un 0.</td>
</tr>
<tr>
<td height="43">CLR</td>
<td width="558">Limpia (del inglés <em>clear</em>) el acumulador. Es decir, pone un 0 en él.</td>
</tr>
<tr>
<td height="43">DEC</td>
<td width="558">Decrementa (del inglés <em>decrease</em>) el acumulador y deja el resultado en el propio acumulador.</td>
</tr>
<tr>
<td height="43">PUSH</td>
<td width="558">Mete el valor del acumulador en la pila.</td>
</tr>
<tr>
<td height="43">POP</td>
<td width="558">Saca el valor de la pila y lo pone en el acumulador.</td>
</tr>
<tr>
<td height="43">CALL &lt;addr&gt;</td>
<td width="558">Del inglés <em>call</em>, llamar. Pone el valor del PC en la pila y pone &lt;addr&gt; en PC.</td>
</tr>
<tr>
<td height="43">RET</td>
<td width="558">Del inglés <em>return</em>, retornar. Saca el valor de la pila y lo pone en el PC.</td>
</tr>
</tbody>
</table>

<p>Esta vez no vamos a ver en detalle cómo se hacen estas instrucciones. Cuando vimos el C16A lo vimos con detalle, pero ahora ya sería detallar demasiado. Además de las dos instrucciones que ya hemos visto para operar con la pila, PUSH y POP, hay otras dos que parecen un poco especiales, ¿no? Es decir, también parece que operan con la pila, pero que también hacen algo más, ¿no? Recuerda que PC (<em>Program Counter</em>) apunta a &#8220;la siguiente instrucción a ejecutar&#8221;, así que &#8220;poner X en PC&#8221; significa &#8220;saltar a X&#8221;. Es decir, son como PUSH y POP respectivamente, pero lo que guardan/sacan es el PC, no el acumulador; y además, saltan.</p>

<p>Vamos a ver para qué sirven con un ejemplo (esta vez no vamos a usar el teclado ni la pantalla para nada, para simplificar el ejemplo al máximo): vamos a calcular el factorial de un número.</p>

<p>Es decir, si el número es el 6, vamos a hacer 6x5x4x3x2x1 = 720. Pero claro, nuestro ordenador no sabe multiplicar&#8230; solo sabe sumar. En el último artículo vimos un truco para multiplicar números enteros positivos: multiplicar PxQ es sumar Q veces P. Pero una preguntita&#8230; ¿esto de multiplicar un número por otro no es algo muy habitual? ¿No podría ocurrírsenos una forma de escribir el &#8220;subprograma de multiplicación&#8221; una sola vez y luego usarlo tantas veces como necesitemos? Muy buena idea, vamos a ello. El programa que hace eso es el siguiente. Prepárate, porque es bastante largo, pero es probablemente lo más largo que vamos a ver en la serie. Esta vez, como es bastante largo, vamos a escribir a la izquierda las direcciones de memoria, porque si no, nos perdemos.</p>

<table width="931" border="0" cellspacing="0" cellpadding="0"><colgroup> <col width="55" /> <col width="171" /> <col width="209" /> <col width="496" /> </colgroup>
<tbody>
<tr>
<td width="55" height="21">0&#215;000</td>
<td width="171">/FACTORIAL</td>
<td width="209">LD /NUMERO</td>
<td width="496"></td>
</tr>
<tr>
<td height="21">0&#215;001</td>
<td></td>
<td>BRZ /FINFACTORIAL</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;002</td>
<td></td>
<td>PUSH</td>
<td># R=R*N</td>
</tr>
<tr>
<td height="21">0&#215;003</td>
<td></td>
<td>LD /RESULTADO</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;004</td>
<td></td>
<td>PUSH</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;005</td>
<td></td>
<td>CALL /MULTIPLICAR</td>
<td># Llama a la subrutina MULTIPLICAR</td>
</tr>
<tr>
<td height="21">0&#215;006</td>
<td></td>
<td>POP</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;007</td>
<td></td>
<td>ST /RESULTADO</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;008</td>
<td></td>
<td>LD /NUMERO</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;009</td>
<td></td>
<td>DEC</td>
<td></td>
</tr>
<tr>
<td height="21">0x00A</td>
<td></td>
<td>ST /NUMERO</td>
<td></td>
</tr>
<tr>
<td height="21">0x00B</td>
<td></td>
<td>BR /FACTORIAL</td>
<td></td>
</tr>
<tr>
<td height="21">0x00C</td>
<td>/FINFACTORIAL</td>
<td>NOP</td>
<td># Al llegar aquí, RESULTADO tiene el resultado</td>
</tr>
<tr>
<td height="21">0x00D</td>
<td>/HALT</td>
<td>NOP</td>
<td></td>
</tr>
<tr>
<td height="21">0x00E</td>
<td></td>
<td>BR /HALT</td>
<td></td>
</tr>
<tr>
<td height="21">0x00F</td>
<td>/NUMERO</td>
<td>6</td>
<td># El numero del que hay que calcular el factorial</td>
</tr>
<tr>
<td height="21">0&#215;010</td>
<td>/RESULTADO</td>
<td>1</td>
<td># Resultado parcial y final del factorial</td>
</tr>
<tr>
<td height="21">0&#215;011</td>
<td>/MULTIPLICAR</td>
<td>POP</td>
<td># Subrutina MULTIPLICAR</td>
</tr>
<tr>
<td height="21">0&#215;012</td>
<td></td>
<td>ST /RETORNO</td>
<td># Saco la direccion de retorno de la pila y la guardo en RETORNO</td>
</tr>
<tr>
<td height="21">0&#215;013</td>
<td></td>
<td>POP</td>
<td># Saco los dos parametros de la pila y los ugardo en P y Q</td>
</tr>
<tr>
<td height="21">0&#215;014</td>
<td></td>
<td>ST /P</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;015</td>
<td></td>
<td>POP</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;016</td>
<td></td>
<td>ST /Q</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;017</td>
<td></td>
<td>CLR</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;018</td>
<td></td>
<td>ST /RES</td>
<td># Ponemos RES a 0</td>
</tr>
<tr>
<td height="21">0&#215;019</td>
<td>/MULTIPLICACION</td>
<td>LD /P</td>
<td></td>
</tr>
<tr>
<td height="21">0x01A</td>
<td></td>
<td>BRZ /FINMULTIPLICACION</td>
<td># Bucle mutiplicacion</td>
</tr>
<tr>
<td height="21">0x01B</td>
<td></td>
<td>DEC</td>
<td></td>
</tr>
<tr>
<td height="21">0x01C</td>
<td></td>
<td>ST /P</td>
<td></td>
</tr>
<tr>
<td height="21">0x01D</td>
<td></td>
<td>LD /RES</td>
<td></td>
</tr>
<tr>
<td height="21">0x01E</td>
<td></td>
<td>ADD /Q</td>
<td></td>
</tr>
<tr>
<td height="21">0x01F</td>
<td></td>
<td>ST /RES</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;020</td>
<td></td>
<td>BR /MULTIPLICACION</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;021</td>
<td>/FINMULTIPLICACION</td>
<td>PUSH</td>
<td># Guardo en la pila el resultado</td>
</tr>
<tr>
<td height="21">0&#215;022</td>
<td></td>
<td>LD /RETORNO</td>
<td># Guardo en la pila la dirección de retorno</td>
</tr>
<tr>
<td height="21">0&#215;023</td>
<td></td>
<td>PUSH</td>
<td></td>
</tr>
<tr>
<td height="21">0&#215;024</td>
<td>/FINMULTIPLICAR</td>
<td>RET</td>
<td># Retornar</td>
</tr>
<tr>
<td height="21">0&#215;025</td>
<td>/RETORNO</td>
<td>0&#215;000</td>
<td># Direccion de retorno de la subrutina</td>
</tr>
<tr>
<td height="21">0&#215;026</td>
<td>/P</td>
<td>0</td>
<td># Primer multiplicando</td>
</tr>
<tr>
<td height="21">0&#215;027</td>
<td>/Q</td>
<td>0</td>
<td># Segundo multiplicando</td>
</tr>
<tr>
<td height="21">0&#215;028</td>
<td>/RES</td>
<td>0</td>
<td># Resultado multiplicacion</td>
</tr>
</tbody>
</table>

<p>A ver si logramos entenderlo. Lo mejor es quitarnos rápido de en medio las cosas que son fáciles: las líneas con el /HALT son igual que antes, para terminar ahí. /NUMERO contiene inicialmente el número del que queremos calcular el factorial y /RESULTADO es donde dejaremos el resultado, obviamente, el factorial.</p>

<p>Luego, lo mejor es ir entendiendo bloques sencillitos. Veamos&#8230; las líneas 0&#215;000 a 0&#215;001 y 0&#215;008 a 0x00B, ¿qué hacen? Ojo, que estoy olvidándome de momento de lo que hay entre medias: solo esas seis líneas. ¿Qué hacen? Ya lo hemos visto antes: carga una dirección de memoria y la van decrementando hasta que llega a 1. Esa dirección de memoria es /NUMERO, así que esas 6 líneas van contando hacia atrás 6, 5, 4, 3, 2, 1&#8230; y entre medias parece que hacen algo con ese /NUMERO. ¿Entendido esto?</p>

<p>Entonces, ¿qué está haciendo con ese /NUMERO entre medias, en las líneas 0&#215;002 a 0&#215;007? Primero mete /NUMERO en la pila. Luego mete /RESULTADO en la pila. Luego llama a /MULTIPLICAR. Y luego saca algo de la pila y lo guarda en /RESULTADO.</p>

<p>Uhm&#8230; no acabo de entenderlo del todo&#8230;</p>

<p>¿Y si intentamos entender qué hace esa llamada a /MULTIPLICAR? Recuerdas que el <em>CALL /MULTIPLICAR</em> lo que hace es saltar a /MULTIPLICAR, metiendo previamente en la pila el valor actual de PC, ¿verdad? Y una vez que llega a /MULTIPLICAR, ¿qué hace? Son las líneas 0&#215;011 a 0&#215;022. De esas líneas, si lo miramos con cuidado, hay un pedazo que ya sabemos qué hace: lo que hay entre la 0&#215;017 y la 0x01E es lo mismo que en el artículo anterior usábamos para multiplicar dos números: sumar P veces Q. El resultado de esa multiplicación acaba en /RES.</p>

<p>Así que lo único raro es lo que hay alrededor de eso. Lo que hace es: sacar un valor de la pila y guardarlo en /RETORNO. Sacar un elemento de la pila y guardarlo en /P. Sacar otro valor de la pila y guardarlo en /Q. Luego multiplica con el bucle que ya hemos visto. Luego mete /RES en la pila. Luego mete /RETORNO en la pila. Y luego llama a RET. Sabemos que RET lo que hace es saltar a donde diga la última entrada de la pila.</p>

<p>¿Lo vas viendo? Vamos a verlo un poco más en abstracto:</p>

<table width="568" border="0" cellspacing="0" cellpadding="0"><colgroup> <col width="243" /> <col width="325" /> </colgroup>
<tbody>
<tr>
<td width="243" height="21"><strong>Bucle principal</strong></td>
<td width="325"><strong>Subrutina: MULTIPLICAR</strong></td>
</tr>
<tr>
<td height="21"></td>
<td></td>
</tr>
<tr>
<td height="21">Guardo /NUMERO en la pila</td>
<td></td>
</tr>
<tr>
<td height="21">Guardo /RESULTADO en la pila</td>
<td></td>
</tr>
<tr>
<td height="21">Llamo a la subrutina</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>Saco de la pila a /RETORNO</td>
</tr>
<tr>
<td height="21"></td>
<td>Pongo 0 en /RES</td>
</tr>
<tr>
<td height="21"></td>
<td>Saco de la pila a /Q</td>
</tr>
<tr>
<td height="21"></td>
<td>Saco de la pila a /P</td>
</tr>
<tr>
<td height="21"></td>
<td>Multiplico /P x /Q y el resultado va a /RES</td>
</tr>
<tr>
<td height="21"></td>
<td>Pongo /RES en la pila</td>
</tr>
<tr>
<td height="21"></td>
<td>Pongo /RETORNO en la pila</td>
</tr>
<tr>
<td height="21"></td>
<td>Retorno</td>
</tr>
<tr>
<td height="21">Saco de la pila a /RESULTADO</td>
<td></td>
</tr>
</tbody>
</table>

<p>La gracia de esto es que lo que el &#8220;programa principal&#8221; mete en la pila, la &#8220;subrutina&#8221; lo saca y lo utiliza. Cuando acaba, mete en la pila el resultado, que será extraído por el programa principal.</p>

<p>¡Estupendo! ¡Eso es una subrutina!<sup>[<a href="https://eltamiz.com/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/#footnote_1_19066" id="identifier_1_19066" class="footnote-link footnote-identifier-link" title="Dependiendo del sistema se le llama subrutina, rutina, subprograma, funci&oacute;n, procedimiento, m&eacute;todo&amp;#8230;">2</a>]</sup></p>

<p>Todas las subrutinas funcionan más o menos así:</p>

<ul>
    <li>Quien va a llamarlas mete en la pila los parámetros de la subrutina, en un cierto orden prefijado que es el que espera la subrutina.</li>
    <li>La subrutina hace lo que tenga que hacer, que puede ser incluso llamar a otras subrutinas (¡o incluso llamarse a sí misma!), y pone el resultado en la pila.<sup>[<a href="https://eltamiz.com/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/#footnote_2_19066" id="identifier_2_19066" class="footnote-link footnote-identifier-link" title="Por cierto: el factorial lo hemos calculado con un algoritmo iterativo. La forma elegante y sencilla de hacerlo es con un algoritmo recursivo, que se basa en que factorial(N) = N*factorial(N-1). Pero no quer&iacute;a contar ambas cosas a la vez para no liar m&aacute;s a los lectores sin experiencia en estas lides.">3</a>]</sup></li>
    <li>La subrutina termina devolviendo el control a su llamador (especificando la próxima instrucción a ejecutar, que es la siguiente a la instrucción CALL).</li>
    <li>Quien llamó saca de la pila el resultado y continúa su proceso.</li>
</ul>

<p>¡Es un invento maravilloso! Podemos hacer subrutinas para multiplicar, restar, contar, comparar, esperar&#8230; Y después, las vamos combinando unas con otras para hacer rutinas más complejas: rutinas que hagan logaritmos, que calculen sudokus o que preparen café con leche. Y luego, desde el programa principal las vamos llamando. Esta es la única forma razonable de hacer programas complejos. Gran parte del trabajo de los programadores consiste en organizar estas subrutinas de forma lo más inteligente posible para que el programa funcione rápido, sea fácil de mantener en el futuro, se programe rápidamente&#8230;</p>

<p>Por lo tanto, hemos hecho una subrutina que multiplica los dos números que le pasemos como parámetros. Recapitulemos entonces: teníamos un bucle que contaba de 6 hacia abajo, hasta llegar a 1: 6, 5, 4, 3, 2, 1. Y, dentro de ese bucle, tenemos que el resultado es el resultado [anterior] multiplicado por el número. Es decir, vamos multiplicando 1&#215;6. Luego el resultado de eso lo multiplicamos x5. El resultado de eso x4&#8230; Y así hasta llegar a 1. ¡Eso es el factorial! Lo hemos conseguido: nuestro programa calcula el factorial de un número.<sup>[<a href="https://eltamiz.com/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/#footnote_3_19066" id="identifier_3_19066" class="footnote-link footnote-identifier-link" title="Date cuenta de que no tenemos ninguna instrucci&oacute;n para comprobar si es un 1, que podr&iacute;amos ahorr&aacute;rnoslo, y por eso tenemos que perder el tiempo multiplicando por 1.">4</a>]</sup></p>

<p>Muchas veces utilizamos algún tipo de pseudocógico para ir explicando lo que va haciendo de forma un poco más abstracta. Por ejemplo, podemos decir:</p>

<table width="488" border="0" cellspacing="0" cellpadding="0"><colgroup> <col width="319" /> <col width="169" /> </colgroup>
<tbody>
<tr>
<td width="319" height="21">numero = 6</td>
<td width="169">Línea 0x00F</td>
</tr>
<tr>
<td height="21">resultado = 1</td>
<td>Línea 0&#215;010</td>
</tr>
<tr>
<td height="21">mientras (numero != 0) {</td>
<td>Líneas 0&#215;000, 0&#215;001</td>
</tr>
<tr>
<td height="21">  resultado = multiplicar(resultado,numero)</td>
<td>Líneas 0&#215;002 a 0&#215;007</td>
</tr>
<tr>
<td height="21">  numero = numero -1</td>
<td>Líneas 0&#215;008 a 00A</td>
</tr>
<tr>
<td height="21">}</td>
<td>Líneas 0x00B</td>
</tr>
<tr>
<td height="21"># El resultado está en resultado</td>
<td></td>
</tr>
<tr>
<td height="21">subrutina multiplicar(p, q) {</td>
<td>Líneas 0&#215;011 a 0&#215;016</td>
</tr>
<tr>
<td height="21">  res = 0</td>
<td>Líneas 0&#215;017, 0&#215;018</td>
</tr>
<tr>
<td height="21">  mientras (p != 0) {</td>
<td>Líneas 0&#215;019, 0x01A</td>
</tr>
<tr>
<td height="21">    p = p -1</td>
<td>Líneas 0x01B, 0x01C</td>
</tr>
<tr>
<td height="21">    res = res + q</td>
<td>Líneas 0x01D a 0x01F</td>
</tr>
<tr>
<td height="21">  }</td>
<td>Línea 0&#215;020</td>
</tr>
<tr>
<td height="21">  devolver res</td>
<td>Líneas 0&#215;021 a 0&#215;024</td>
</tr>
<tr>
<td height="21">}</td>
<td></td>
</tr>
</tbody>
</table>

<p>Fíjate en que es lo mismo, pero puesto de una forma un poco más abstracta&#8230; eso es lo que veremos en el próximo capítulo.</p>

<p>&nbsp;</p>

<p>&nbsp;</p>
<ol class="footnotes"><li id="footnote_0_19066" class="footnote">Técnicamente, en español se denomina la &#8220;cabeza de la pila&#8221;, y sacar un elemento de la pila con un POP, lo llamamos &#8220;descabezar&#8221; la pila.</li><li id="footnote_1_19066" class="footnote">Dependiendo del sistema se le llama subrutina, rutina, subprograma, función, procedimiento, método&#8230;</li><li id="footnote_2_19066" class="footnote">Por cierto: el factorial lo hemos calculado con un algoritmo iterativo. La forma elegante y sencilla de hacerlo es con un algoritmo recursivo, que se basa en que factorial(N) = N*factorial(N-1). Pero no quería contar ambas cosas a la vez para no liar más a los lectores sin experiencia en estas lides.</li><li id="footnote_3_19066" class="footnote">Date cuenta de que no tenemos ninguna instrucción para comprobar si es un 1, que podríamos ahorrárnoslo, y por eso tenemos que perder el tiempo multiplicando por 1.</li></ol>]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2013/12/01/computador-magico-xxv-ordenador-c16b-subrutinas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<item>
		<title>Computador mágico XXIV &#8211; Ordenador C16A IV: temporizador</title>
		<link>https://eltamiz.com/elcedazo/2013/11/03/computador-magico-xxiv-ordenador-c16a-iv-temporizador/</link>
		<comments>https://eltamiz.com/elcedazo/2013/11/03/computador-magico-xxiv-ordenador-c16a-iv-temporizador/#comments</comments>
		<pubDate>Sun, 03 Nov 2013 08:43:49 +0000</pubDate>
		<dc:creator>J</dc:creator>
				<category><![CDATA[Electrónica]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[J]]></category>

		<guid isPermaLink="false">http://eltamiz.com/elcedazo/?p=19017</guid>
		<description><![CDATA[La serie &#8220;El computador mágico&#8221; está disponible también en forma de libro. En el último capítulo de la serie vimos el &#8220;hola mundo&#8221; de los programas para el C16A. Hoy vamos a profundizar un poco en él, haciendo un programa un poco más complejo: vamos a hacer un temporizador como el que hicimos con lógica [...]]]></description>
			<content:encoded><![CDATA[<div align="left">
<table class="bookBox" border="1" cellspacing="1" cellpadding="1">
<tbody>
<tr>
<td valign="center">
<p style="text-align: center; margin-top: 1px; margin-bottom: 1px; margin-left: 1px;" align="center"><a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liimagelink"><img class="aligncenter size-full wp-image-18513" title="Computador mágico" src="http://eltamiz.com/elcedazo/wp-content/uploads/2016/01/ComputadorMagicoDigest_v21_cover_v1_front2.png" alt="" width="90" height="128" /></a></p>
</td>
<td valign="center">

<p style="text-align: left;" align="center">
La serie &#8220;El computador mágico&#8221; está disponible también <a href="/elcedazo/2016/01/31/computador-magico-el-libro/" class="liinternal">en forma de libro</a>.
</p>
</td>
</tr>
</tbody>
</table>
</div>

<p>En el <a href="http://eltamiz.com/elcedazo/2013/10/05/computador-magico-xxiii-ordenador-c16a-iii-hola-mundo/" target="_blank" class="liinternal">último capítulo</a> de <a href="http://eltamiz.com/elcedazo/series/computador-magico/" target="_blank" class="liinternal">la serie</a> vimos el &#8220;hola mundo&#8221; de los programas para el C16A. Hoy vamos a profundizar un poco en él, haciendo un programa un poco más complejo: vamos a hacer un temporizador como el que hicimos con <a href="http://eltamiz.com/elcedazo/2013/06/06/computador-magico-xvii-logica-secuencial/" target="_blank" class="liinternal">lógica secuencial</a>.</p>

<p>Como antes, vamos a pegar a continuación el diseño del ordenador y el juego de instrucciones:</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16a_arquitectura2.png" class="liimagelink"><img class="aligncenter size-full wp-image-18988" title="j_computador_c16a_arquitectura2" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_c16a_arquitectura2.png" alt="" width="784" height="352" /></a></p>

<p>&nbsp;</p>

<table width="683" border="1" cellspacing="0" cellpadding="0"><colgroup> <col width="125" /> <col width="558" /> </colgroup>
<tbody>
<tr>
<td width="125" height="21"><strong>Mnemotécnico</strong></td>
<td width="558"><strong>¿Qué hace?</strong></td>
</tr>
<tr>
<td height="43">NOP</td>
<td width="558"><em>No Operation</em>. Operación que no hace nada.</td>
</tr>
<tr>
<td height="43">ST &lt;addr&gt;</td>
<td width="558">Almacena (del inglés <em>store</em>) el contenido del acumulador en la posición de memoria &lt;addr&gt;. addr es del inglés address, dirección.</td>
</tr>
<tr>
<td height="43">LD &lt;addr&gt;</td>
<td width="558">Carga (del inglés <em>load</em>) en el acumulador el contenido de la posición de memoria &lt;addr&gt;.</td>
</tr>
<tr>
<td height="43">ADD &lt;addr&gt;</td>
<td width="558">Suma (del inglés <em>add</em>) el contenido del acumulador con el contenido de la posición de memoria &lt;addr&gt;, y deja el resultado en el acumulador.</td>
</tr>
<tr>
<td height="43">BR &lt;addr&gt;</td>
<td width="558">Salta (del inglés <em>branch</em>) la ejecución a la posición &lt;addr&gt;. E decir, en vez de continuar ejecutando en PC+1, continúa ejecutando en la posición de memoria &lt;addr&gt;</td>
</tr>
<tr>
<td height="43">BZ &lt;addr&gt;</td>
<td width="558">Del inglés <em>branch if zero</em>, salta si es cero. Es decir, lo mismo que BR, pero solo si el contenido del acumulador es un 0.</td>
</tr>
<tr>
<td height="43">CLR</td>
<td width="558">Limpia (del inglés <em>clear</em>) el acumulador. Es decir, pone un 0 en él.</td>
</tr>
<tr>
<td height="43">DEC</td>
<td width="558">Decrementa (del inglés <em>decrease</em>) el acumulador y deja el resultado en el propio acumulador.</td>
</tr>
</tbody>
</table>

<p>Recuerda también que estamos usando lenguaje ensamblador para escribir nuestro programa, de modo que lo que escribamos resulte legible con relativa facilidad.</p>

<p>&nbsp;</p>

<p>Entonces, como decíamos, queremos hacer un programa que espere 3 segundos y luego escriba una &#8220;A&#8221; en pantalla . Desgraciadamente, para que la espera fuera de 3 segundos tendríamos que introducir muchas cosas que aún no hemos visto, de modo que tendremos que simplificarlo un poco: vamos a esperar 3000 &#8220;ciclos&#8221;. Veremos luego cómo ajustarlo para que realmente sean 3 segundos y veremos qué fácil es.</p>

<p>¿Quieres intentar hacer tú el programa? Si sabes programar, te resultará trivial. Si no, dale una pensada antes de seguir.</p>

<p>&#8230;</p>

<p>¿Ya?</p>

<p>El programa que lo logra es el siguiente:</p>

<table width="535" border="0" cellspacing="0" cellpadding="0"><colgroup> <col width="155" /> <col width="130" /> <col width="250" /> </colgroup>
<tbody>
<tr>
<td width="155" height="21">0&#215;000</td>
<td width="130">LD /TIEMPO</td>
<td width="250"></td>
</tr>
<tr>
<td height="21">/ESPERA</td>
<td>DEC</td>
<td># Espera durante TIEMPO ciclos</td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /FIN</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>BR /ESPERA</td>
<td></td>
</tr>
<tr>
<td height="21">/FIN</td>
<td>LD /LETRA</td>
<td># Escribe LETRA…</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /PANTALLA1</td>
<td># … en PANTALLA1</td>
</tr>
<tr>
<td height="21">/HALT</td>
<td>NOP</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>BR /HALT</td>
<td></td>
</tr>
<tr>
<td height="21">/TIEMPO</td>
<td>3000</td>
<td># Tiempo de espera</td>
</tr>
<tr>
<td height="21">/LETRA</td>
<td>&#8216;A&#8217;</td>
<td># Letra para el aviso</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
<tr>
<td height="21">/PANTALLA1 0&#215;800</td>
<td>0&#215;0000</td>
<td># Zona de I/O</td>
</tr>
</tbody>
</table>

<p>Supongo que, como el programa es sencillito, lo entiendes sin problemas. Al empezar, carga en el acumulador el valor que hay en /TIEMPO (es decir, 3000). Luego lo decrementa, por lo que ya vale 2999. Fíjate ahora en el truco: el BRZ de la 3ª línea dice que, si el acumulador es 0, salte a la línea /FIN. Pero el acumulador no es 0, sino 2999, con lo cual no salta, y continúa por la línea 4ª. Pero la línea 4ª es un salto a /ESPERA&#8230; pues nada, allá que se va. Es decir, hemos vuelto atrás.</p>

<p>Por lo tanto, volverá a decrementar el acumulador, que pasará a valer 2998. Obviamente, volverá a pasar por el BRZ, y como sigue sin ser 0, volverá a continuar por el BR, que volverá a saltar a /ESPERA&#8230; así una y otra vez&#8230; ¿cuántas veces? Pues 3000 veces. Porque cuando haya pasado por ahí 3000 veces, esta vez sí, el acumulador valdrá 0, y cuando pase por el BRZ /FIN, como el acumulador sí que será 0, entonces saltará a /FIN. ¿Entendido?</p>

<p>Ya solo queda que, cuando llegue ahí, cargue en el acumulador lo que hay en la posición /LETRA, que es una &#8216;A&#8217;, y lo escribe en la posición /PANTALLA1, que es nuestra pantalla. Finalmente, entra en el mismo bucle infinito que veíamos en el capítulo anterior.</p>

<p>Fácil, ¿verdad?</p>

<p>Bueno, pues hemos conseguido lo que queríamos. Con un pequeño detalle: no sabemos cuánto va a tardar esto en realidad. Pero es más fácil de lo que parece, y nos sirve para demostrar la potencia de esta aproximación. Ahora vamos y encendemos el ordenador, y con un cronómetro medimos el tiempo que transcurre desde que encendemos hasta que se escribe la &#8220;A&#8221; en la pantalla. Supongamos, por ejemplo, que hemos medido 15s. Entonces ya sabemos que con 3000 &#8220;ciclos&#8221;, tenemos 15s. Con una simple regla de 3 sabemos que cada segundo son 200 ciclos.</p>

<p>¿Qué debemos hacer ahora para que nuestro diseño de verdad espere 3s? Muy sencillo: cambiamos el programa por el siguiente:</p>

<table width="535" border="0" cellspacing="0" cellpadding="0"><colgroup> <col width="155" /> <col width="130" /> <col width="250" /> </colgroup>
<tbody>
<tr>
<td width="155" height="21">0&#215;000</td>
<td width="130">LD /TIEMPO</td>
<td width="250"></td>
</tr>
<tr>
<td height="21">/ESPERA</td>
<td>DEC</td>
<td># Espera durante TIEMPO ciclos</td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /FIN</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>BR /ESPERA</td>
<td></td>
</tr>
<tr>
<td height="21">/FIN</td>
<td>LD /LETRA</td>
<td># Escribe LETRA…</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /PANTALLA1</td>
<td># … en PANTALLA1</td>
</tr>
<tr>
<td height="21">/HALT</td>
<td>NOP</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>BR /HALT</td>
<td></td>
</tr>
<tr>
<td height="21">/TIEMPO</td>
<td>600</td>
<td># Tiempo de espera</td>
</tr>
<tr>
<td height="21">/LETRA</td>
<td>&#8216;A&#8217;</td>
<td># Letra para el aviso</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
<tr>
<td height="21">/PANTALLA1 0&#215;800</td>
<td>0&#215;0000</td>
<td># Zona de I/O</td>
</tr>
</tbody>
</table>

<p>Fíjate en que el único cambio es que en vez de poner 3000 en /TIEMPO, ahora pone 600.</p>

<p>¡Tachán! Ahora ya espera 3s.</p>

<p>¿Y si queremos que, en vez de 3s, espere 11s? Pues lo mismo: ponemos 2200 en la posición /TIEMPO y volvemos a encenderlo.</p>

<p>Date cuenta de la diferencia enorme que esto supone respecto al circuito secuencial que <a href="http://eltamiz.com/elcedazo/2013/06/06/computador-magico-xvii-logica-secuencial/" target="_blank" class="liinternal">veíamos anteriormente</a>. En aquel momento diseñamos con mucho cuidado un circuito muy sencillo que contaba hasta 3. Pero si queríamos contar hasta 11, por ejemplo, teníamos que cambiar el circuito de arriba a abajo: teníamos que añadir más biestables, cambiar la lógica de realimentación, cambiar la etapa de salida&#8230; en fin, había que rehacer el circuito por completo. Ahora, en cambio, tenemos un sistema que es muuuuuucho más complejo inicialmente. Date cuenta también de que ahora tenemos una ALU, una unidad de control, memoria&#8230; es mucho más complejo. Pero, a cambio, modificar el tiempo de espera es trivial. Solo hemos tenido que cambiar el valor inicial de una de las palabras de la memoria. Y no solo eso, sino que ahora podemos hacer programas mucho más complejos.</p>

<p>Vamos con un ejemplo. Ten presente que también tenemos un teclado&#8230; pues vamos a aprovecharlo. Lo que vamos a hacer es un programa que haga lo siguiente: al arrancar, que no haga nada. Cuando pulse una de las teclas, esperaremos tantos segundos como corresponda al valor decimal de la tecla pulsada y luego mostraremos la tecla pulsada. Por ejemplo, si el usuario pulsa la tecla &#8220;F&#8221;, esperaremos 70 segundos y luego mostraremos una &#8220;F&#8221; en pantalla. Si en cambio pulsa la &#8220;b&#8221;, esperaremos 98 segundos y luego mostraremos la &#8220;b&#8221; (recuerda que los caracteres de control los pintaremos simplemente como un cuadrado <img src="https://eltamiz.com/elcedazo/wp-content/cache/tex_12889c5f93db54fa936d8a765d4eae57.png" align="absmiddle" class="tex" alt="\diamond" />). Vamos a recordar aquí el teclado para que no tengas que estar yendo a buscarlo.</p>

<p><a href="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_teclado_teclas1.png" class="liimagelink"><img class="aligncenter size-full wp-image-19048" title="j_computador_teclado_teclas" src="http://eltamiz.com/elcedazo/wp-content/uploads/2012/06/j_computador_teclado_teclas1.png" alt="" width="781" height="284" /></a></p>

<p>Bueno, pues el programa que logra eso es el siguiente:</p>

<table width="810" border="0" cellspacing="0" cellpadding="0"><colgroup> <col width="171" /> <col width="209" /> <col width="430" /> </colgroup>
<tbody>
<tr>
<td width="171" height="21">/TECLA 0&#215;000</td>
<td width="209">LD /TECLADO</td>
<td width="430"></td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /TECLA</td>
<td># Espero a que se pulse una tecla</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /PULSADA</td>
<td># Me guardo la tecla pulsada</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /CONTADOR</td>
<td></td>
</tr>
<tr>
<td height="21">/MULTIPLICACION</td>
<td>LD /CONTADOR</td>
<td># Bucle multiplicador PULSADA*SEGUNDO</td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /FINMULTIPLICACION</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>DEC</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ST /CONTADOR</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>LD /SUMATORIO</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ADD /SEGUNDO</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>ST /SUMATORIO</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>BR /MULTIPLICACION</td>
<td></td>
</tr>
<tr>
<td height="21">/FINMULTIPLICACION</td>
<td>LD /SUMATORIO</td>
<td># Al llegar aqui, SUMATORIO=PULSADA*SEGUNDO</td>
</tr>
<tr>
<td height="21">/ESPERA</td>
<td>DEC</td>
<td># Espera durante SUMATORIO ciclos</td>
</tr>
<tr>
<td height="21"></td>
<td>BRZ /FINESPERA</td>
<td></td>
</tr>
<tr>
<td height="21"></td>
<td>BR /ESPERA</td>
<td></td>
</tr>
<tr>
<td height="21">/FINESPERA 0&#215;010</td>
<td>LD /PULSADA</td>
<td># Al llegar aqui, han pasado PULSADA segundos</td>
</tr>
<tr>
<td height="21"></td>
<td>ST /PANTALLA1</td>
<td></td>
</tr>
<tr>
<td height="21">/HALT</td>
<td>NOP</td>
<td># Fin</td>
</tr>
<tr>
<td height="21"></td>
<td>BR /HALT</td>
<td></td>
</tr>
<tr>
<td height="21">/SEGUNDO</td>
<td>200</td>
<td># Un segundo (los ciclos que tarda un segundo)</td>
</tr>
<tr>
<td height="21">/PULSADA</td>
<td>0&#215;0000</td>
<td># Donde guardare la tecla pulsada</td>
</tr>
<tr>
<td height="21">/SUMATORIO</td>
<td>0&#215;0000</td>
<td># Donde ire calculando la multiplicacion</td>
</tr>
<tr>
<td height="21">/CONTADOR</td>
<td>0&#215;0000</td>
<td># Donde ire almacenando el contador de la multiplicacion</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
<tr>
<td height="21">/PANTALLA1 0&#215;800</td>
<td>0&#215;0000</td>
<td># Pantalla</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
<tr>
<td height="21">/TECLADO 0&#215;820</td>
<td>0&#215;0000</td>
<td># Teclado</td>
</tr>
<tr>
<td height="21"></td>
<td>…</td>
<td></td>
</tr>
</tbody>
</table>

<p>Si nunca has programado, es probable que entender esto te resulte complicado, y tengas que darle un par de vueltas. Lo que vamos a hacer es un programa asequible y voy a ayudarte, pero es posible que requiera que lo leas un par de veces hasta que lo entiendas. Haz el esfuerzo, porque una vez que entiendas esto habrás entendido buena parte del trabajo técnico de los programadores.</p>

<p>Empezamos casi por el final, definiendo las constantes y variables que vamos a usar. Definimos que /SEGUNDO es 200, porque ya hemos medido antes que con 200 ciclos gastamos 1 segundo. Definimos también /PULSADA, /SUMATORIO y /CONTADOR para almacenar variables: en /PULSADA guardaremos la tecla que se ha pulsado. /SUMATORIO y /CONTADOR los usaremos luego para unos bucles&#8230; luego los explicamos. /PANTALLA1 y /TECLADO son, como antes, para leer del teclado y escribir en la pantalla.</p>

<p>Bueno, pues empecemos a ejecutar por el principio. Las dos primeras líneas lo que hacen es leer /TECLADO, y si es un 0, volver a la línea 0&#215;000, donde vuelve a leerlo&#8230; una y otra vez&#8230; hasta que /TECLADO no sea un 0. Si te acuerdas, el teclado empezaba con un 0, y se rellenaba luego el valor de la tecla pulsada. Así que lo que estamos haciendo aquí es esperar a que el usuario pulse una tecla. Cuando la pulse, ya no habrá un 0, y entonces seguirá por la línea 0&#215;002. En las líneas 0&#215;002 y 0&#215;003 simplemente se guarda la tecla pulsada tanto en /PULSADA como en /CONTADOR.</p>

<p>Las líneas desde /MULTIPLICACION hasta /FINMULTIPLICACION, ¿qué hacen? Muy sencillo: sabemos que multiplicar 3*6 es sumar 3+3+3+3+3+3, ¿verdad? Pues eso es lo que hace: si ya he pasado /CONTADOR veces por el bucle, salgo del bucle hacia /FINMULTIPLICACION; y si no, decremento /CONTADOR en uno, para que a la siguiente pasada pueda volver a comprobarlo (líneas 0&#215;004 a 0&#215;007). Dentro del bucle, sumo /SUMATORIO + /SEGUNDO y guardo el resultado en /SUMATORIO (líneas 0&#215;008 a 0x00A). Finalmente, en la 0x00B salto de vuelta a /MULTIPLICACION, para cerrar el bucle.</p>

<p>Es decir, lo que haré es /SUMATORIO = /SEGUNDO + /SEGUNDO +/ SEGUNDO + /SEGUNDO +&#8230; ¿cuántas veces? Tantas veces como valiera /CONTADOR inicialmente&#8230; es decir, tantas como el valor numérico de la tecla que haya pulsado.</p>

<p>El caso es que antes o después el BRZ de la línea 0&#215;005 saltará a /FINMULTIPLICACION&#8230; y en ese momento /SUMATORIO contiene el resultado de la multiplicación. Lo que hay entre la 0x00C y la 0x00F es lo mismo que antes: una espera durante /SUMATORIO ciclos. Es lo mismo que vimos en el primer programa de esta capítulo, así que nos saltamos la explicación.</p>

<p>Finalmente, cuando llega a /FINESPERA, han pasado los segundos acordados,<sup>[<a href="https://eltamiz.com/elcedazo/2013/11/03/computador-magico-xxiv-ordenador-c16a-iv-temporizador/#footnote_0_19017" id="identifier_0_19017" class="footnote-link footnote-identifier-link" title="Date cuenta de que hemos despreciado el tiempo que se tarda en calcular la multiplicaci&oacute;n, y que eso podr&iacute;a no ser despreciable. Podr&iacute;amos arreglarlo, simplemente estimando cu&aacute;nto se tarda en hacer la multiplicaci&oacute;n y rest&aacute;ndolo antes de hacer la espera. Como lo importante aqu&iacute; no es si yo s&eacute; programar o no, sino c&oacute;mo funciona la m&aacute;quina, dejamos eso como ejercicio, si quer&eacute;is. Como pista, puedes darte cuenta de que el tiempo que se tarda en hacer la multiplicaci&oacute;n es lineal con el valor num&eacute;rico de la tecla pulsada, y eso tambi&eacute;n es lineal, por requisito, con el tiempo que queremos esperar. En fin, no sigo, que si no lo resuelvo entero.">1</a>]</sup> así que pasamos el valor de /PULSADA (que, te recuerdo, contenía la tecla que habíamos leído del teclado en la línea 0&#215;000) a /PANTALLA1, saliendo por la pantalla. Luego ya solo queda el bucle de fin que hemos usado siempre.</p>

<p>Vamos a repasarlo, de forma un poco más abstracta, a ver si te ayuda a entenderlo:</p>

<ul>
    <li>Leemos del teclado hasta que lo que leamos sea distinto de 0.</li>
    <li>Guardamos el resultado de la tecla pulsada.</li>
    <li>Multiplicamos el valor de la tecla pulsada por el valor de /SEGUNDO, para saber cuántos ciclos debemos esperar. Pero como nuestra ALU no multiplica, solo suma, tenemos que implementar la multiplicación como sumar <em>n</em>veces:
<ul>
    <li>Si ya he sumado esas <em>n</em> veces, he terminado y salgo del bucle.</li>
    <li>Si no, añado /SEGUNDO al resultado y decremento en 1 el contador para que se vuelva a comprobar en el siguiente paso por el bucle.</li>
</ul>
</li>
    <li>/SUMATORIO tiene el número ciclos que debo esperar. Así que hago una espera como la del primer programa de este capítulo.</li>
    <li>Finalmente, copio la tecla pulsada (que me la había guardado) en la pantalla y entro en la espera de final de programa.</li>
</ul>

<p>Lo que hemos hecho aquí no está exento de problemas, pero eso lo veremos en próximos artículos. Dedícale una segunda lectura a estos párrafos, porque si no has programado nunca es normal que te resulte un poco complicado de entender.</p>

<p>En el próximo capítulo ampliaremos nuestro ordenador C16A para que haga alguna cosa más, y lo llamaremos C16B.</p>

<p>&nbsp;</p>
<ol class="footnotes"><li id="footnote_0_19017" class="footnote">Date cuenta de que hemos despreciado el tiempo que se tarda en calcular la multiplicación, y que eso podría no ser despreciable. Podríamos arreglarlo, simplemente estimando cuánto se tarda en hacer la multiplicación y restándolo antes de hacer la espera. Como lo importante aquí no es si yo sé programar o no, sino cómo funciona la máquina, dejamos eso como ejercicio, si queréis. Como pista, puedes darte cuenta de que el tiempo que se tarda en hacer la multiplicación es lineal con el valor numérico de la tecla pulsada, y eso también es lineal, por requisito, con el tiempo que queremos esperar. En fin, no sigo, que si no lo resuelvo entero.</li></ol>]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2013/11/03/computador-magico-xxiv-ordenador-c16a-iv-temporizador/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
	</channel>
</rss>
