<?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; Ingeniería</title>
	<atom:link href="https://eltamiz.com/elcedazo/category/ingenieria/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>AlphaZero: Un avance muy significativo de la Inteligencia Artificial</title>
		<link>https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/</link>
		<comments>https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#comments</comments>
		<pubDate>Tue, 26 Dec 2017 12:18:20 +0000</pubDate>
		<dc:creator>Macluskey</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Ingeniería]]></category>
		<category><![CDATA[Macluskey]]></category>

		<guid isPermaLink="false">https://eltamiz.com/elcedazo/?p=57145</guid>
		<description><![CDATA[A principios de diciembre leí una noticia que me impactó bastante. La leí en El País, en las páginas deportivas correspondientes a los deportes minoritarios, firmada por Leontxo García, el magnífico corresponsal especialista de El País en ajedrez, que mantiene una interesantísima sección denominada “La Pasión del Ajedrez”.[1] El titular del artículo era nada menos [...]]]></description>
			<content:encoded><![CDATA[<p>A principios de diciembre leí una noticia que me impactó bastante. <a href="https://elpais.com/elpais/2017/12/07/ciencia/1512667534_598950.html" target="_blank" class="liexternal">La leí en El País</a>, en las páginas deportivas correspondientes a los deportes minoritarios, firmada por Leontxo García, el magnífico corresponsal especialista de El País en ajedrez, que mantiene una interesantísima sección denominada “La Pasión del Ajedrez”.<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_0_57145" id="identifier_0_57145" class="footnote-link footnote-identifier-link" title="En otros tiempos yo jugu&eacute; al ajedrez a nivel de aficionado, bastante mal, por cierto. Ahora me gusta seguir de vez en cuando partidas de maestros, aunque reconozco que a duras penas las entiendo.">1</a>]</sup> El titular del artículo era nada menos que «<em>Jaque mate del “Messi de los chips</em>”»&#8230; a algún genio se le debió ocurrir que utilizando a modo de reclamo el nombre del futbolista argentino igual conseguía más clics en la noticia. En realidad el titular correcto debería haber sido algo como “<strong>Prepárense: la singularidad tecnológica, más cerca</strong>”, sólo que entonces, sin ese “Messi” en el título, seguro que no hubiera clicado casi nadie&#8230; En fin. El caso es que, aunque ha tenido mucha repercusión entre los jugadores de ajedrez y que bastantes medios tradicionales han publicado artículos contando con más o menos detalle la noticia, estoy seguro de que habrá pasado bastante inadvertida para el público en general entre el marasmo diario de información que nos llega cada día por diferentes medios.</p>

<p>El resumen del artículo en un único párrafo podría ser algo como: “<em>AlphaZero, una IA creada y entrenada por DeepMind, la división de Inteligencia Artificial de Google, ha derrotado en un match a Stockfish, considerado el mejor programa actual de ajedrez</em>”.</p>

<div id="attachment_57149" class="wp-caption alignleft" style="width: 240px"><a href="https://eltamiz.com/elcedazo/wp-content/uploads/2017/12/tablero_ajedrez.png" class="liimagelink"><img class="size-full wp-image-57149" title="Tablero de Ajedrez" src="https://eltamiz.com/elcedazo/wp-content/uploads/2017/12/tablero_ajedrez.png" alt="" width="230" height="230" /></a><p class="wp-caption-text">Tablero de Ajedrez</p></div>

<p>O sea, un nuevo programa que juega al ajedrez ha derrotado al vigente campeón&#8230; ¡Menuda novedad! Es lo que lleva pasando los últimos 40 ó 50 años: que cada programa es más rápido, más potente y juega mejor que el anterior. En definitiva, poca cosa, ¿no?</p>

<p>Pues no. <strong>En mi opinión, esta vez no</strong>.</p>

<p>En este largo artículo intentaré convenceros de que esta noticia trasciende con mucho del especializado mundo del ajedrez, que esta vez es muy diferente y que esa derrota de Stockfish por parte de un “novato” como es AlphaZero es bastante significativa de que las cosas que tienen que ver con la inteligencia artificial, esta vez sí, están cambiando. Y no sé si es para bien o&#8230; o no.</p>

<p>Si eres jugador de ajedrez seguramente este artículo te sobre, porque conocerás todo lo que viene a continuación y mucho más. El artículo está destinado a quienes no tengan demasiada idea de ajedrez ni sigan el estado del arte de los programas de ajedrez, y pretende explicar las implicaciones últimas que tiene este evento extraordinario.</p>

<p>Eso sí: para contar bien el porqué de mi sorpresa no me queda más remedio, por ser fiel a mi dicharachero estilo, que comenzar por el principio e ir paso a paso&#8230; Tarde o temprano llegaré al meollo de lo que quiero contaros, pero me parece muy importante aquí fijar bien las bases históricas y tecnológicas para que se comprenda bien todo el asunto. Paciencia, pues.</p>

<h1><strong>BREVE HISTORIA DEL JUEGO DEL AJEDREZ</strong></h1>

<p>El <a href="https://es.wikipedia.org/wiki/Ajedrez" target="_blank" rel="nofollow" class="liwikipedia">ajedrez</a> es un juego de estrategia para dos personas, que van jugando alternativamente moviendo sus piezas, blancas las de un jugador y negras las del otro, por un tablero de 8&#215;8 escaques.<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_1_57145" id="identifier_1_57145" class="footnote-link footnote-identifier-link" title="Escaque es cada una de las casillas blancas y negras (o al menos claras y oscuras) del tablero.">2</a>]</sup> Originario inicialmente de India, se conoce en su forma actual desde hace al menos quinientos o seiscientos años: a mediados del siglo XV se fijaron las reglas del juego tal y como las conocemos ahora y desde entonces se ha jugado ininterrumpidamente hasta nuestras fechas. Y cada día más.</p>

<p>Siendo como es un juego de <a href="/elcedazo/2011/08/21/teoria-de-juegos-xxix-wargames-5/" target="_blank" class="liinternal">información completa</a><sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_2_57145" id="identifier_2_57145" class="footnote-link footnote-identifier-link" title="Ambos jugadores poseen una informaci&oacute;n perfecta tanto de la situaci&oacute;n de las piezas propias y del contrincante como de las reglas; no hay informaci&oacute;n oculta de ning&uacute;n tipo.">3</a>]</sup> y con un elevadísimo número de partidas posibles, desde casi el principio de su expansión los jugadores vieron la necesidad de estudiar la teoría del juego para mejorar sus posibilidades de victoria. Y así comenzó el estudio sistemático de las aperturas, el de los finales, las diferentes estrategias del juego medio, etc. En los tres o cuatro párrafos que siguen voy a citar nombres de aperturas o de posiciones concretas con la jerga típica del ajedrez, pero sin describirlas en absoluto. Si no conocéis bien el juego, de todos modos leed estos párrafos aunque no sepáis a qué me refiero con lo de “apertura siciliana”, “peón pasado”, etc, porque lo importante de todo esto, que desarrollaré a continuación, tiene bastante que ver con todo este inmenso <em>corpus</em> de conocimiento sobre el juego que se ha ido acumulando a través de los siglos.</p>

<p>Efectivamente, multitud de jugadores de todos los tiempos han utilizado ingentes cantidades de esfuerzo y tiempo en analizar hasta el más mínimo detalle los intríngulis de las diferentes aperturas:<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_3_57145" id="identifier_3_57145" class="footnote-link footnote-identifier-link" title="Apertura: Formas distintas de comenzar el juego. Suele comprender los primeros doce o quince movimientos de cada jugador.">4</a>]</sup> la Española,<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_4_57145" id="identifier_4_57145" class="footnote-link footnote-identifier-link" title="As&iacute; nombrada en honor a Ruy L&oacute;pez de Segura, cl&eacute;rigo espa&ntilde;ol que la populariz&oacute; en el siglo XVI, y que sigue siendo posiblemente la apertura m&aacute;s jugada en la actualidad.">5</a>]</sup> la Siciliana, la Francesa, el Gambito de Dama, las Defensas Indias de Rey o Dama&#8230; Hay varias docenas de aperturas diferentes que se juegan con regularidad, todas ellas muy bien estudiadas. Y se escribieron tratados y compendios que estudiaban estas aperturas, tratados que con el tiempo quedaban obsoletos y eran sustituidos por otros nuevos&#8230; Lo poco que yo sé sobre aperturas lo aprendí estudiando el monumental trabajo del gran maestro internacional checo Ludek Pachman: cuatro volúmenes publicados a finales de los años 60 del siglo pasado que compendiaron todo el saber ajedrecístico del momento sobre los diferentes tipos de aperturas en el ajedrez.</p>

<div id="attachment_57150" class="wp-caption alignright" style="width: 444px"><a href="https://eltamiz.com/elcedazo/wp-content/uploads/2017/12/Ajedrez-Staunton.jpg" class="liimagelink"><img class="size-full wp-image-57150" title="Ajedrez Staunton" src="https://eltamiz.com/elcedazo/wp-content/uploads/2017/12/Ajedrez-Staunton.jpg" alt="" width="434" height="299" /></a><p class="wp-caption-text">Listos para comenzar la partida</p></div>

<p>El mismo trabajo se hizo con los finales: son perfectamente conocidas las técnicas a usar cuando en el tablero quedan muy pocas piezas, y todo jugador decente sabe cómo dar mate sólo con torre, o con dos alfiles, o con alfil y caballo, etc, así como la forma coronar un peón o, en su caso, evitar la coronación cuando sólo hay peones y reyes en el tablero, etc.</p>

<p>Y el mismo esfuerzo y tiempo, o incluso más, se ha usado secularmente en comprender las características deseables de las posiciones de ajedrez (además de las obvias: diferencia de material –piezas– entre uno y otro jugador, amenazas concretas al rey, la dama, etc), por ejemplo la existencia de peones pasados, de columnas abiertas o semiabiertas, la posición del rey (en el centro o enrocado), la obtención de la calidad o la importancia de mantener la pareja de alfiles, entre muchos otros detalles más o menos procelosos que, sin embargo, los jugadores tienen en cuenta para evaluar una posición.</p>

<p>El ajedrez está considerado como el juego de estrategia entre dos jugadores por antonomasia (con permiso del Go que, aunque es de complejidad similar o incluso mayor, no cuenta ni de lejos con el enorme número de aficionados que juegan regularmente al ajedrez). Los jugadores dedicaban, y dedican, horas y más horas al entrenamiento, a conocer cada variante de cada apertura, a encontrar los puntos fuertes y débiles de cada posición, a analizar con el máximo detalle cada partida, cada variante, cada jugada, todo en aras de mejorar su juego y vencer al rival.</p>

<p>Y entonces&#8230; llegaron los ordenadores.</p>

<h1><strong>LOS ORDENADORES Y EL AJEDREZ</strong></h1>

<p>Los primeros ordenadores eran mamotretos enormes, carísimos y con poquísima capacidad, incluso para la época. Y se usaban para <em>Cosas-Verdaderamente-Importantes</em>, como derrotar a la Alemania nazi en la Segunda Guerra Mundial,<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_5_57145" id="identifier_5_57145" class="footnote-link footnote-identifier-link" title="Esto hizo Colossus, el primer aut&eacute;ntico ordenador creado en Bletchley Park, Inglaterra, para descifrar el c&oacute;digo Enigma usado por los alemanes.">6</a>]</sup> o calcular los parámetros necesarios para que estallaran las bombas nucleares,<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_6_57145" id="identifier_6_57145" class="footnote-link footnote-identifier-link" title="Richard Feynman, por ejemplo, cuenta su trabajo dentro del Proyecto Manhattan en el Laboratorio de Los &Aacute;lamos calculando precisamente esto.">7</a>]</sup> o poner un cacharro en el espacio, incluso con habitantes dentro&#8230; Pero pronto los incipientes ingenieros e informáticos volvieron su atención al ajedrez, con el ánimo de programar un software que fuera capaz de jugar lo mejor posible. El motivo es claro: el ajedrez es un juego con reglas precisas y no demasiado complicadas, pero que son capaces de generar tantas partidas diferentes como átomos tiene el universo,<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_7_57145" id="identifier_7_57145" class="footnote-link footnote-identifier-link" title="Vale, a lo mejor exagero, pero en cualquier caso el n&uacute;mero de partidas posibles es de un uno y un mont&oacute;n de ceros detr&aacute;s.">8</a>]</sup> y es de información completa, así que resulta idóneo para su programación en ordenadores, y además está bien estudiado en cuanto a técnicas poderosas de juego que facilitan la elección de la próxima jugada en la esperanza de que sea la mejor.</p>

<p>En una palabra, <strong>el ajedrez es perfecto para investigar nuevas técnicas de evaluación y decisión que luego pudieran ser extrapoladas a otros campos más interesantes y productivos</strong>.<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_8_57145" id="identifier_8_57145" class="footnote-link footnote-identifier-link" title="Pongo esta frase en negrita porque es el quid de todo el asunto. Recordadla para dentro de un rato.">9</a>]</sup></p>

<p>Tan pronto como en 1976 o 1977 tuve yo una asignatura en <a href="https://eltamiz.com/elcedazo/series/historia-de-un-viejo-informatico/" target="_blank" class="liexternal">mi ya olvidada carrera</a> que trataba, entre otros temas absolutamente novedosos en la época, sobre cómo atacar la programación de un software que jugara al ajedrez de manera&#8230; digamos que algo más sofisticada que un principiante. Por ejemplo, un serio problema de entonces era la representación del tablero en la memoria del ordenador: era vital poder codificar la posición de las piezas en el tablero de forma que la información fuera completa pero que ocupara el mínimo espacio posible&#8230; ¡los ordenadores de la época tenían 8, 16 o, en el mejor de los casos, 32 Kb de memoria!<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_9_57145" id="identifier_9_57145" class="footnote-link footnote-identifier-link" title="Kb: Kilobyte, o sea, 1.024 bytes cada uno. Un ordenador de la &eacute;poca ten&iacute;a 16.384 octetos o, en el mejor de los casos, 32.768. Es decir, uno o dos millones de veces menos que esa min&uacute;scula tarjeta de memoria que tienes en tu c&aacute;mara de fotos o en tu tel&eacute;fono m&oacute;vil&amp;#8230;">10</a>]</sup> y había que ahorrar cada byte. Todo programa que juega al ajedrez en primer lugar genera todas las jugadas que sean posibles en la posición, las evalúa de una u otra forma y luego procede a calcular de la misma manera las posibles respuestas del contrincante para cada una de ellas, posiblemente no de todas, sino sólo de las seleccionadas&#8230; y este proceso se repite algunas veces, tantas como niveles de análisis alcance el juego. En cuanto se analizan así tres o cuatro niveles (claramente insuficientes para jugar decentemente), se genera un árbol con un número de tableros representados que crece de forma exponencial, y si no hay memoria para almacenarlos y compararlos entre sí&#8230; mala cosa.</p>

<p>Una vez determinada la representación más idónea (y compacta), hay que evaluar la posición resultante&#8230; y no una sola, claro, sino todas ellas, para determinar mediante un valor numérico si es buena o mala para las blancas o las negras. Por ejemplo, valores positivos dan ventaja a las blancas y negativos, a las negras. Y aquí es donde de verdad los ingenieros se toparon con un problema. Un problema serio, en apariencia irresoluble: ¿cómo valorar una determinada posición de las piezas en el tablero? Existían, ya lo dije, libros, muchos libros sobre estrategia ajedrecística en las diferentes fases de la partida, pero esas normas y reglas generales tenían montañas de excepciones, cuando no eran directamente contradictorias. Algo muy difícil de compilar en un programa, máxime con las limitadas capacidades de aquellos cacharros antediluvianos. No obstante, se fueron haciendo los primeros pinitos.</p>

<p>Los primeros programas jugaban muy mal. Quizás podían ganar a un principiante que acabara de aprender las reglas, pero no a un jugador aficionado ni mucho menos a un maestro. La principal limitación estribaba, obviamente, en la incapacidad de analizar muchos niveles de juego, como hace un maestro habitualmente cuando analiza una posición, debido a la escasa capacidad de cálculo. El método de evaluación iba paulatinamente mejorando, pero la falta de potencia de los ordenadores impedía jugar una partida decente en tiempo razonable. Se implementaron algoritmos de podado del árbol, el más conocido el llamado “<a href="https://es.wikipedia.org/wiki/Poda_alfa-beta" target="_blank" rel="nofollow" class="liwikipedia">alpha-beta</a>”, que elimina para su análisis posterior todos aquellos nodos (jugadas) que son aparentemente malas&#8230; y entiéndase <em>aparentemente malas</em> en base a la imperfecta valoración que de las posiciones se efectuaban por entonces. Pero, claro, con los años los ordenadores fueron mejorando en prestaciones y bajando de precio. Y aquellos toscos programas fueron a su vez mejorando, y los ingenieros y programadores, aprendiendo por el camino.</p>

<div id="attachment_57151" class="wp-caption alignright" style="width: 400px"><a href="https://eltamiz.com/elcedazo/wp-content/uploads/2017/12/390px-Novag_Constellation_Forte.jpg" class="liimagelink"><img class="size-full wp-image-57151" title="390px-Novag_Constellation_Forte" src="https://eltamiz.com/elcedazo/wp-content/uploads/2017/12/390px-Novag_Constellation_Forte.jpg" alt="" width="390" height="293" /></a><p class="wp-caption-text">La Novag Constellation Forte. ¡Qué gran máquina!, sobre todo teniendo en cuenta que salió al mercado en 1986&#8230;</p></div>

<p>A finales de los ochenta ya había máquinas comerciales que jugaban aceptablemente a nivel aficionado. En 1988 yo me compré, pagando una auténtica fortuna, una máquina Novag Constellation Forte con la que he pasado muchos momentos placenteros&#8230; ¡y eso que casi siempre me ganaba! Vale, sí, a mí me ganaba (y me sigue ganando, conste), pero a un maestro no le resistiría ni un asalto.<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_10_57145" id="identifier_10_57145" class="footnote-link footnote-identifier-link" title="Las caracter&iacute;sticas de la Novag eran impresionantes para una m&aacute;quina de ajedrez de la &eacute;poca: procesador con 5 Mhz de velocidad de reloj, 64 Kb de memoria ROM y nada menos que 4 Kb de memoria RAM. S&iacute;, Kb, no Gb, ni siquiera Mb.">11</a>]</sup> Pues bien, ésa era la impresión general de la época: <em>por muy bien que llegue a jugar un ordenador, pasarán muchas décadas antes de que sea capaz de ganar a un maestro, y no digamos a un Gran Maestro&#8230; ¡o al Campeón del Mundo!</em> Y había incluso quien decía que <em>nunca jamás</em> se produciría tal evento.</p>

<p>Pues bien, <strong>exactamente eso pasó el día 10 de febrero de 1996, cuando <a href="https://es.wikipedia.org/wiki/Deep_Blue_(computadora)" target="_blank" rel="nofollow" class="liwikipedia">Deep Blue</a> derrotó a Gary Kasparov</strong>, el entonces invencible campeón del mundo en lo más excelso de su juego. Deep Blue era un superordenador IBM RS/6000 con 30 procesadores P2SC de 120 Mhz ampliados con 480 procesadores VLSI y un software específicamente diseñado para jugar al ajedrez. Lo basó todo en la fuerza bruta: con sus centenares de procesadores trabajando en paralelo calculaba unos cien millones de posiciones por segundo, un logro espectacular en esa fecha. Kasparov ganó de todos modos ese duelo a seis partidas por 4-2, a pesar de perder una de ellas,<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_11_57145" id="identifier_11_57145" class="footnote-link footnote-identifier-link" title="De las cinco restantes partidas, Kasparov gan&oacute; 3 y empat&oacute; las otras dos.">12</a>]</sup> pero al año siguiente el sucesor de Deep Blue (denominado, en un alarde de imaginación, <em>Deeper Blue</em>) derrotó finalmente a Kasparov en otro match a seis partidas por 3,5 a 2,5, ganando dos partidas, perdiendo una y haciendo tres veces tablas.</p>

<p>Estos dos duelos fueron el pistoletazo de salida para la imparable progresión de los programas que juegan al ajedrez. Vinieron Arasan, Rebel 3D, Chessmaster, Fritz&#8230; cada uno con más potencia y capacidad que el anterior. Se aprovechaban no sólo del increíble salto de potencia de los ordenadores, sino del cada vez mayor y mejor uso de técnicas de evaluación de las posiciones. Tanto era así que los jugadores humanos crearon <a href="https://es.wikipedia.org/wiki/T%C3%A1cticas_anticomputador" target="_blank" rel="nofollow" class="liwikipedia">estrategias nuevas para competir con las nuevas generaciones de programas ajedrecísticos</a>, haciendo movimientos muy conservadores a largo plazo, o bien entregando un peón “gratis” a cambio de un mejor desarrollo, etc. Pero estas nuevas tácticas tampoco duraron mucho. Los programas de ajedrez fueron mejorando, incorporando nuevas habilidades o recursos, aprovechando la creciente potencia del hardware&#8230; <strong>Ahora ya no hay un humano que sea capaz de ganar consistentemente a las máquinas jugando al ajedrez</strong>. Ya no, hace años que no.</p>

<p>La forma de clasificar a los jugadores de ajedrez es mediante un sistema llamado “<a href="https://es.wikipedia.org/wiki/Sistema_de_puntuaci%C3%B3n_Elo" target="_blank" rel="nofollow" class="liwikipedia">Sistema de puntuación ELO</a>”,<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_12_57145" id="identifier_12_57145" class="footnote-link footnote-identifier-link" title="Curiosamente, ELO no es un acr&oacute;nimo, sino el apellido del inventor del sistema, el h&uacute;ngaro Arpad Elo.">13</a>]</sup> que va quitando o poniendo puntos a los jugadores en función de los resultados de sus partidas con otros jugadores. Básicamente, se comparan los ELO’s previos de ambos jugadores y en función del resultado real de la partida se trasvasan puntos de uno a otro jugador. Pues bien, en el momento de juntar estas letras, el jugador con <a href="https://2700chess.com/" target="_blank" class="liexternal">ELO más alto</a> es precisamente el campeón mundial, el noruego Magnus Carlsen, con un valor de ELO de entre 2.833 y 2.986 dependiendo de si son partidas tradicionales (o sea, largas), cortas o relámpago. Y seguramente ese 2.986 en partidas blitz -o sea, las rapidísimas: 5 minutos para 40 movimientos- sea el valor más alto jamás alcanzado por un jugador en la historia, o estará muy cerca.</p>

<p>Pues bien, el campeón mundial de programas de ajedrez es <a href="https://es.wikipedia.org/wiki/Stockfish_(ajedrez)" target="_blank" rel="nofollow" class="liwikipedia">Stockfish</a>, con otros como Houdini, Komodo o Rybka muy cerca de él. Se trata de un programa de código abierto, es decir, gratuito, que tiene reconocido un ELO de&#8230; ¡3.400 puntos!<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_13_57145" id="identifier_13_57145" class="footnote-link footnote-identifier-link" title="&iexcl;Y hasta de 3.650 en partidas r&aacute;pidas!">14</a>]</sup> Es decir, entre 550 y 600 puntos más que Carlsen, el actual campeón mundial que es, posiblemente, el jugador más fuerte de la historia.<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_14_57145" id="identifier_14_57145" class="footnote-link footnote-identifier-link" title="Los jugadores actuales &ndash;el propio Carlsen, Kariakin, Caruana, Aronian, Nakamura, etc&ndash; tienen la ventaja de tener a su disposici&oacute;n todos estos programas para poder entrenarse con ellos, lo que les permite ir mucho m&aacute;s all&aacute; en su estudio del juego de lo que nunca pudieron ir genios como Capablanca, Alekhine, Tal, Bobby Fischer o el propio Kasparov. Por ello es opini&oacute;n generalizada que son m&aacute;s fuertes que cualquier otro jugador de la historia, por genial que &eacute;ste fuera.">15</a>]</sup> En un duelo entre Carlsen y Stockfish, o cualquier otro programa de potencia similar, no cabe la menor duda de quién obtendría la victoria. Y no sería Carlsen, precisamente.</p>

<p>Son, en definitiva, programas muy sofisticados, que incorporan siglos de conocimiento del juego, que se apoyan en: <em>a)</em> completísimos libros de aperturas que compilan prácticamente todas las aperturas conocidas;<em> b)</em> exhaustivas <a href="https://es.wikipedia.org/wiki/Base_de_datos_de_tablas_de_finales" target="_blank" rel="nofollow" class="liwikipedia">bases de datos de finales</a>, que muestran el camino exacto, la mejor jugada posible para conseguir la victoria en posiciones del final de partida, con pocas piezas en juego; <em>c)</em> elaborados mecanismos de evaluación de las posiciones atendiendo a centenares de parámetros posicionales y tácticos refinados durante muchos años de experiencia analítica; y <em>d)</em> poderosos y muy eficientes algoritmos de poda de los árboles resultantes, para elegir las jugadas más prometedoras en las que profundizar el análisis. Y todo ello con un potente hardware que les permite analizar decenas de millones de movimientos por segundo.</p>

<p>En una palabra: estos programas para jugar al ajedrez son el resultado de millones de horas de análisis, investigación y estudio tanto de jugadores y analistas de ajedrez como de ingenieros e informáticos. Son el culmen del desarrollo humano para jugar a este juego tan especial. Son&#8230; perfectos.</p>

<p>¿<em>Perfectos</em>?</p>

<h1><strong>CUANDO TODOS ERAN FELICES&#8230; ENTONCES LLEGO ALPHAZERO</strong></h1>

<p>Como hemos visto, Stockfish, Houdini y otros programas han sido desarrollados paso a paso con los algoritmos específicos más avanzados para comprender el juego del ajedrez y la experiencia acumulada a lo largo de los años. Representan lo que podríamos llamar “la aproximación del ingeniero” para resolver un problema. Sin embargo, hay otra aproximación diferente para aprender a jugar al ajedrez, que es básicamente la que utiliza un niño al que se le enseñan las reglas básicas: <strong>el ensayo-error</strong>. El niño recién enseñado de momento no sabe nada de la apertura española, ni de las ventajas de clavar las piezas, ni de la forma de dar mate con sólo una torre: lo que hace es comenzar a jugar partidas moviendo las piezas según se le va ocurriendo y aprender del resultado.<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_15_57145" id="identifier_15_57145" class="footnote-link footnote-identifier-link" title="As&iacute; aprendieron Capablanca o Bobby Fischer, por citar s&oacute;lo a dos genios del ajedrez.">16</a>]</sup> Aprende que sacar a pasear la dama a las primeras de cambio no suele ser una buena elección, a evitar el mate pastor y que una torre vale más que un caballo. Con el tiempo, poco a poco, empieza a dominar los aspectos de la táctica y la estrategia&#8230; y entonces quedará irremisiblemente atrancado, hasta que algún vecino amable le regale un libro de aperturas o sobre táctica y descubra que todo lo que ha aprendido a golpe de partidas perdidas se puede aprender en los libros que han escrito otros que, a su vez, han aprendido en libros que han escrito otros más, que a su vez&#8230; Y comenzará a usar programas que mejoren su juego y su análisis, y a contrastar su sapiencia en torneos con la del resto de jugadores que, básicamente, han aprendido como él mismo. Eventualmente, si te llamas Magnus Carlsen y eres un superdotado para este juego llegarás a ganar el campeonato mundial. Varias veces.</p>

<p>Lo que parece evidente es que el aprendizaje por ensayo y error está limitado: llegará un momento en que será casi imposible mejorar a base de jugar partidas sin saber nada de aperturas, ni de finales, ni de bla, bla, bla&#8230; ¿no?</p>

<p>Pues parece que no. <strong>Porque así, precisamente así es como AlphaZero ha aprendido lo que sabe</strong>. Y sabe mucho.</p>

<p>Desde hace mediados de los 70 se conocen diversas técnicas de lo que se llama “Inteligencia Artificial”. En los años 90, los que molaban eran los “<a href="https://es.wikipedia.org/wiki/Sistema_experto" target="_blank" rel="nofollow" class="liwikipedia">Sistemas Expertos</a>”, que iban aprendiendo el comportamiento del mundo según se lo explicaban expertos humanos que les enseñaban qué decisiones tomarían ellos ante una cierta situación. Aquello cayó finalmente en el olvido, o casi, debido a la dificultad de que los expertos humanos pudieran coherentemente razonar el porqué de sus decisiones, y entonces se pensó que lo idóneo era que las IAs aprendieran solitas. En consecuencia se inventaron las “<a href="https://es.wikipedia.org/wiki/Red_neuronal_artificial" target="_blank" rel="nofollow" class="liwikipedia">redes neuronales</a>” y el &#8220;<a href="https://es.wikipedia.org/wiki/Aprendizaje_autom%C3%A1tico" target="_blank" rel="nofollow" class="liwikipedia">aprendizaje automático</a>&#8221; (<em>machine learning</em>). Se basan en crear una suerte de “neuronas” virtuales organizadas en diferentes capas, a las que se entregan unos ciertos datos de entrada y una salida esperada, para que aprendan de estos datos reales. Por ejemplo, se les entregan miles o millones de letras “a” manuscritas (que un humano ha determinado previamente que son, efectivamente, aes), y la red se va automodificando (modifica los pesos que aplica en cada capa a cada característica básica) para ir comprendiendo la estructura íntima de lo que los humanos llamamos “a”. Si todo va bien, al final la red será capaz de identificar qué es una “a” manuscrita, posiblemente mejor incluso que los propios humanos.</p>

<div id="attachment_57158" class="wp-caption alignleft" style="width: 310px"><a href="https://eltamiz.com/elcedazo/wp-content/uploads/2017/12/deepmind-alphazero-ai.jpg" class="liimagelink"><img class="size-medium wp-image-57158" title="deepmind-alphazero-ai" src="https://eltamiz.com/elcedazo/wp-content/uploads/2017/12/deepmind-alphazero-ai-300x168.jpg" alt="" width="300" height="168" /></a><p class="wp-caption-text">AlphaZero, creado por DeepMind</p></div>

<p>Pues bien, AlphaZero, creada por <a href="https://es.wikipedia.org/wiki/Google_DeepMind" target="_blank" rel="nofollow" class="liwikipedia">DeepMind, la división de IA de Google</a>, es una red neuronal. Con suficientes capas y un algoritmo de aprendizaje general que, en principio, sirve para casi todo, lo que normalmente quiere decir para bastante poco; ya se sabe el antiguo dicho: aprendiz de mucho, maestro de nada. Es decir, <strong>no está especializada en ajedrez</strong>. No tiene un gigantesco libro de aperturas que le guíe por los intrincados comienzos de las partidas. No conoce los valores teóricos de cada pieza, afinados tras siglos de análisis. No tiene una completa tabla de finales que indique la forma correcta de jugar estas posiciones. No sabe nada de la estrategia del juego medio, ni de los trucos tácticos ni de cómo valorar las interioridades de ciertas posiciones. A AlphaZero únicamente se le han enseñado las reglas del juego: cómo mueven las fichas, cómo se comen, cómo promocionan los peones al llegar a la octava fila y, por supuesto, cuál es el objetivo de la partida, que es zamparse al rey enemigo.<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_16_57145" id="identifier_16_57145" class="footnote-link footnote-identifier-link" title="En realidad nadie se come al rey: se anuncia jaque-mate, es decir, que a la pr&oacute;xima el rey ser&aacute; indefectiblemente comido, y se termina la partida sin darse el real fest&iacute;n, aunque en la pr&aacute;ctica magistral es raro que se d&eacute; mate: el jugador abandona antes de eso, cuando ve que tiene la partida perdida.">17</a>]</sup> En una palabra, <strong>Alphazero no tiene ni idea de todos aquellos sibilinos detalles que hacen realmente fuertes a los programas especializados y, por ende, a los jugadores humanos.</strong> Es únicamente una red neuronal profunda y un algoritmo tipo <em>tabula rasa</em> para reforzar el aprendizaje. No usa el algoritmo “alpha-beta”, ni tampoco el “minimax”, los habituales en programas de ajedrez, sino uno mucho más genérico: un <a href="https://es.wikipedia.org/wiki/M%C3%A9todo_de_Montecarlo" target="_blank" rel="nofollow" class="liwikipedia">algoritmo de tipo MonteCarlo</a> para optimizar la selección de valores. Nada más.</p>

<p>A Alphazero, tras enseñarle las reglas, le han puesto a entrenarse jugando contra sí mismo, es decir, a entrenar su red neuronal por ensayo-error: hago un movimiento más o menos aleatorio tras otro, primero con blancas, luego con negras y, al final, uno de los dos bandos da mate. Y eso es bueno, luego los movimientos que hizo ese jugador deben ser mejores que los del que perdió. Con esta información se retroalimenta la red. Y repetimos el proceso usando los nuevos pesos de la red. Una y otra vez. Hasta hace no mucho diríamos que necesitaría muchos millones de repeticiones para jugar a nivel de jugador de club&#8230; y lo de llegar a jugar a nivel de maestro es ya otro cantar que difícilmente se puede alcanzar trabajando exclusivamente de esta forma.</p>

<p>Sin embargo, algo en el horizonte intuía que esto podría cambiar: una versión anterior de esta red, llamada AlphaGo, entrenada básicamente de la misma forma, había vencido en 2016 a Lee Sedol, jugador de Go coreano que es el campeón mundial del juego. Para la posteridad quedó la cara de absoluta incredulidad del pobre Lee ante una cierta jugada de AlphaGo que le desarboló completamente: más de veinte segundos con la boca abierta y ojos como platos antes de exclamar vaya Vd. a saber qué en coreano. Ya dije que el Go es un juego de estrategia si cabe más complicado que el ajedrez. Y siendo como es este AlphaZero un heredero de AlphaGo&#8230;</p>

<h1><strong>LOS HECHOS</strong></h1>

<p>Según el <a href="https://cdn.chess24.com/GzFl-Z4-SVWO-mC9rL6XhQ/original/mastering-chess-and-shogi-by-self-play.pdf" target="_blank" class="lipdf"><em>paper</em> publicado por DeepMind</a>, entrenaron AlphaZero durante 24 horas.<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_17_57145" id="identifier_17_57145" class="footnote-link footnote-identifier-link" title="No queda muy claro si el entrenamiento fue de 4 horas, de 8 o de 24&amp;#8230; en cualquier caso es una nimiedad; poco importa si fueron 8 o 24: en cualquier caso son muy, muy pocas.">18</a>]</sup> En unas 300.000 iteraciones, unas cuatro horas de autojuego, ya había alcanzado el nivel de Stockfish. Al acabar el entrenamiento se programó un duelo con Stockfish versión 8, un match de 100 partidas, 50 con cada color. Stockfish fue configurado con su nivel más fuerte, usando 64 hilos y un Gigabyte para la tabla hash donde evalúa las posiciones. Con esa configuración evalúa unos 70 millones de movimientos por segundo. Es decir, Stockfish jugaba a su máxima potencia posible. El match se jugó. Y el resultado fue&#8230;&#8230;&#8230;&#8230;&#8230; . . . .  .  .  .</p>

<h2 style="text-align: center;"><strong>¡ 28 a 0 ! </strong></h2>

<p>O, si queréis, 64 a 36:<strong> AlphaZero ganó a Stockfish 28 partidas y las 72 restantes fueron tablas</strong>. No perdió ni una. De las 28 partidas ganadas, 25 fueron con blancas<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_18_57145" id="identifier_18_57145" class="footnote-link footnote-identifier-link" title="Las blancas son siempre las que inician el juego y, por tanto, deciden el tipo general de apertura.">19</a>]</sup> y 3 con negras. Y encima, para conseguir tal hazaña sólo necesitó calcular 80.000 movimientos por segundo. No 80 millones: sólo 80.000, casi mil veces menos que Stockfish. Algunos comentaristas inciden en que parece que las condiciones del match, con un minuto de evaluación por movimiento, no son los más adecuados para Stockfish versión 8, la utilizada en el match, y parece que tampoco se le dejó usar su base de datos de finales. Da igual: en el <em>paper</em> publicado se han mostrado como ejemplo 10 partidas de las 100 que jugaron, y en muchos casos AlphaZero ha realizado jugadas que, por decirlo de algún modo, están simplemente fuera de la comprensión actual del ajedrez. Tanto de humanos como de máquinas.</p>

<p>Por ejemplo, hay maestros que aseguran que <a href="http://www.chessgames.com/perl/chessgame?gid=1899418" target="_blank" class="liexternal">la jugada 21 de la sexta partida publicada</a>, <strong>Ag5</strong>, es la mejor jugada del año. O de la década, o del siglo, quién sabe. Un movimiento imposible de ver, incomprensible para humanos, incluso para el propio Stockfish, que ni tan siquiera lo considera en sus análisis por estúpido y perdedor, pero que una vez jugado deja la partida vista para sentencia. Si os interesa, esa partida concreta está maravillosamente comentada por el Gran Maestro Pepe Cuenca en <a href="https://www.youtube.com/watch?v=9nkLJreG21c" target="_blank" class="liexternal">este video</a>. En el mes escaso que Alphazero lleva en el candelero, las 10 partidas publicadas han sido destripadas, analizadas y comentadas muchas veces por una legión de analistas asombrados. El propio Leontxo García, <a href="https://elpais.com/elpais/2017/12/17/media/1513529905_038469.htmlhttp://" target="_blank" class="liexternal">en el comentario a esa misma partida en El País</a>, asegura que &#8220;si existe alguna civilización superior a la humana en otro planeta quizá juegue así de bien&#8230;&#8221;.</p>

<p>No sé cómo calificar estos datos, teniendo en cuenta el fortísimo nivel del rival&#8230; y no quiero pensar qué hubiera pasado de haber jugado con un humano, con <em>cualquier</em> humano. Es como si un partido de fútbol de la Champions acabara 35 a 0, o como si de pronto un corredor de maratón hiciera una marca de una hora y cuarto. Es impensable, es increíble. Es una paliza en toda regla, <strong>una enmienda a la totalidad al modo en que tradicionalmente los informáticos hemos atacado los problemas</strong>&#8230;</p>

<p>&#8230;Y también algo que nos debe preocupar seriamente. Al menos a mí me preocupa. Porque para AlphaZero y sus creadores el ajedrez es simplemente un medio, una mera anécdota.</p>

<h1><strong>LAS IMPLICACIONES</strong></h1>

<p><strong>Lo de menos es que AlphaZero juegue bien al ajedrez</strong>. O al Go, o al Shogi, una especie de ajedrez japonés.<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_19_57145" id="identifier_19_57145" class="footnote-link footnote-identifier-link" title="Incidentalmente, DeepMind us&oacute; la misma red neuronal y los mismos algoritmos para entrenar a AlphaZero a jugar al Go y al Shogi, con tiempos de entrenamiento similares. Pod&eacute;is imaginar el resultado de los duelos contra los programas campeones del mundo de Go, el propio AlphaGo antes mencionado, y Elmo, en Shogi. Palizas de dimensiones b&iacute;blicas, igual que en ajedrez.">20</a>]</sup> De paso, AlphaZero encontró por el camino, y sin ayuda, todas las aperturas más jugadas y analizadas a lo largo de los siglos, las usó frecuentemente y fue capaz de batir a Stockfish y su ingente base de datos una y otra vez, sin perder una sola partida. Reproduzco, en fin, un párrafo lapidario del propio <em>paper</em>:<sup>[<a href="https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/#footnote_20_57145" id="identifier_20_57145" class="footnote-link footnote-identifier-link" title="Que no voy a traducir, es bastante sencillo de comprender.">21</a>]</sup></p>

<p>“<em>The game of chess represented the pinnacle of AI research over several decades. State-of-the-art programs are based on powerful engines that search many millions of positions, leveraging handcrafted domain expertise and sophisticated domain adaptations. AlphaZero is a generic reinforcement learning algorithm – originally devised for the game of Go – that achieved superior results within a few hours, searching a thousand times fewer positions, given no domain knowledge except the rules of chess. Furthermore, the same algorithm was applied without modification to the more challenging game of shogi, again outperforming the state of the art within a few hours</em>”.</p>

<p>Sí, todo lo anterior es lo de menos. Lo de verdad impactante de la noticia es que una red neuronal sin grandes conocimientos de un tema concreto y altamente especializado sea capaz, en tan sólo 24 horas de entrenamiento (o las que sean) jugando contra sí misma, de alcanzar un dominio del juego muy superior al preexistente, con una comprensión de las posiciones lejos del alcance de cualquier otro organismo, esté basado en el carbono o en el silicio. En unas pocas horas de entrenamiento ha aprendido de ajedrez más que todos los humanos y programas juntos durante siglos. Ha encontrado todos los trucos y estrategias que tanto ha costado encontrar a los especialistas, obviamente también alguna nueva desconocida, y todo sin siquiera jugar contra un rival ni enseñanza teórica alguna.</p>

<p>No quiero pensar lo que podría hacer un programa como éste si lo pusieran a analizar <em>Otras-Cosas-Más-Importantes</em>. Relaciones internacionales. Comercio, importación y exportación. Obtención de nuevos medicamentos. Fabricación y logística. Marketing y publicidad. Conducción automática. Gestión energética. Control de Armas. Gestión de conflictos. Reconocimiento de patrones, de caras, de objetos. Y mil cosas más que no se me ocurren, pero que a alguien se le ocurrirán. Cosas que, con toda seguridad, van a analizar. DeepMind es una división de Google, no lo olvidemos, y, que yo sepa, Google es una empresa con ánimo de lucro (como todas, claro), y no una ONG. Y, desde luego, no están solos: hay otras empresas e investigadores punteros trabajando en Inteligencia Artificial. Muchos.</p>

<p>Como antes recalqué, <em>el ajedrez es perfecto para investigar nuevas técnicas de evaluación y decisión que luego pudieran ser extrapoladas a otros campos más interesantes y productivos</em>. La duda es: interesantes y productivos&#8230; ¿<em>para quién</em>?</p>

<p>¿Estará <a href="https://es.wikipedia.org/wiki/Skynet_(Terminator)" target="_blank" rel="nofollow" class="liwikipedia">Skynet</a> más cerca de lo que pensamos?</p>

<p>¡Suerte!</p>

<p>Disfrutad la vida, mientras podáis. Y esta vez va en serio.</p>
<ol class="footnotes"><li id="footnote_0_57145" class="footnote">En otros tiempos yo jugué al ajedrez a nivel de aficionado, bastante mal, por cierto. Ahora me gusta seguir de vez en cuando partidas de maestros, aunque reconozco que a duras penas las entiendo.</li><li id="footnote_1_57145" class="footnote">Escaque es cada una de las casillas blancas y negras (o al menos claras y oscuras) del tablero.</li><li id="footnote_2_57145" class="footnote">Ambos jugadores poseen una información perfecta tanto de la situación de las piezas propias y del contrincante como de las reglas; no hay información oculta de ningún tipo.</li><li id="footnote_3_57145" class="footnote">Apertura: Formas distintas de comenzar el juego. Suele comprender los primeros doce o quince movimientos de cada jugador.</li><li id="footnote_4_57145" class="footnote">Así nombrada en honor a <a href="https://es.wikipedia.org/wiki/Ruy_L%C3%B3pez_de_Segura" target="_blank" rel="nofollow" class="liwikipedia">Ruy López de Segura</a>, clérigo español que la popularizó en el siglo XVI, y que sigue siendo posiblemente la apertura más jugada en la actualidad.</li><li id="footnote_5_57145" class="footnote">Esto hizo Colossus, el primer auténtico ordenador creado en Bletchley Park, Inglaterra, para descifrar el código Enigma usado por los alemanes.</li><li id="footnote_6_57145" class="footnote"><a href="/elcedazo/2015/01/24/has-leido-esta-usted-de-broma-sr-feynman/" target="_blank" class="liinternal">Richard Feynman</a>, por ejemplo, cuenta su trabajo dentro del Proyecto Manhattan en el Laboratorio de Los Álamos calculando precisamente esto.</li><li id="footnote_7_57145" class="footnote">Vale, a lo mejor exagero, pero en cualquier caso el número de partidas posibles es de un uno y un montón de ceros detrás.</li><li id="footnote_8_57145" class="footnote">Pongo esta frase en negrita porque es el quid de todo el asunto. Recordadla para dentro de un rato.</li><li id="footnote_9_57145" class="footnote">Kb: Kilobyte, o sea, 1.024 bytes cada uno. Un ordenador de la época tenía 16.384 octetos o, en el mejor de los casos, 32.768. Es decir, uno o dos millones de veces menos que esa minúscula tarjeta de memoria que tienes en tu cámara de fotos o en tu teléfono móvil&#8230;</li><li id="footnote_10_57145" class="footnote">Las características de la Novag eran impresionantes para una máquina de ajedrez de la época: procesador con 5 Mhz de velocidad de reloj, 64 Kb de memoria ROM y nada menos que 4 Kb de memoria RAM. Sí, Kb, no Gb, ni siquiera Mb.</li><li id="footnote_11_57145" class="footnote">De las cinco restantes partidas, Kasparov ganó 3 y empató las otras dos.</li><li id="footnote_12_57145" class="footnote">Curiosamente, ELO no es un acrónimo, sino el apellido del inventor del sistema, el húngaro Arpad Elo.</li><li id="footnote_13_57145" class="footnote">¡Y hasta de 3.650 en partidas rápidas!</li><li id="footnote_14_57145" class="footnote">Los jugadores actuales –el propio Carlsen, Kariakin, Caruana, Aronian, Nakamura, etc– tienen la ventaja de tener a su disposición todos estos programas para poder entrenarse con ellos, lo que les permite ir mucho más allá en su estudio del juego de lo que nunca pudieron ir genios como Capablanca, Alekhine, Tal, Bobby Fischer o el propio Kasparov. Por ello es opinión generalizada que son más fuertes que cualquier otro jugador de la historia, por genial que éste fuera.</li><li id="footnote_15_57145" class="footnote">Así aprendieron Capablanca o Bobby Fischer, por citar sólo a dos genios del ajedrez.</li><li id="footnote_16_57145" class="footnote">En realidad nadie <em>se come al rey</em>: se anuncia jaque-mate, es decir, que a la próxima el rey será indefectiblemente comido, y se termina la partida sin darse el real festín, aunque en la práctica magistral es raro que se dé mate: el jugador abandona antes de eso, cuando ve que tiene la partida perdida.</li><li id="footnote_17_57145" class="footnote">No queda muy claro si el entrenamiento fue de 4 horas, de 8 o de 24&#8230; en cualquier caso es una nimiedad; poco importa si fueron 8 o 24: en cualquier caso son muy, muy pocas.</li><li id="footnote_18_57145" class="footnote">Las blancas son siempre las que inician el juego y, por tanto, deciden el tipo general de apertura.</li><li id="footnote_19_57145" class="footnote">Incidentalmente, DeepMind usó la misma red neuronal y los mismos algoritmos para entrenar a AlphaZero a jugar al Go y al Shogi, con tiempos de entrenamiento similares. Podéis imaginar el resultado de los duelos contra los programas campeones del mundo de Go, el propio AlphaGo antes mencionado, y Elmo, en Shogi. Palizas de dimensiones bíblicas, igual que en ajedrez.</li><li id="footnote_20_57145" class="footnote">Que no voy a traducir, es bastante sencillo de comprender.</li></ol>]]></content:encoded>
			<wfw:commentRss>https://eltamiz.com/elcedazo/2017/12/26/alphazero-un-avance-muy-significativo-de-la-inteligencia-artificial/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-nc-nd/2.5/es/</creativeCommons:license>
	</item>
		<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>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>
