cursos:ensamblador:introduccion

Introducción y conceptos básicos


Todo aquel que haya programado en BASIC conocerá sin duda la principal limitación de este sencillo lenguaje de alto nivel: es lento, muy lento. A cambio de su sencillez pagamos una penalización enorme en velocidad.

BASIC es un lenguaje de alto nivel interpretado, lo que quiere decir que el Spectrum (más bien el intérprete BASIC integrado en la ROM) tiene que leer línea a línea nuestro programa, escrito en un lenguaje comprensible para los humanos, decodificar lo que estamos diciendo en este lenguaje, traducirlo a instrucciones comprensibles por el procesador y ejecutarlo, todo ello en tiempo real, línea a línea y comando a comando.

Eso implica que cada vez que se ejecuta el programa BASIC, para cada línea del programa se ejecuta un proceso de lectura, decodificación, traducción y ejecución. Este proceso es lento e implica que no sólo se está ejecutando nuestro programa sino que debajo de él tenemos al intérprete de BASIC realizando todas estas tareas y restándonos parte de la potencia de CPU del Spectrum, que ya de por sí no es especialmente potente.

No importa lo elegantemente optimizado que esté nuestro programa en BASIC, el proceso de interpretación en sí hará que se ejecute con una lentitud que no podemos salvar.

BASIC tiene una serie de trucos más o menos conocidos para acelerar su ejecución: escribir muchas instrucciones en una sóla línea BASIC, poner las rutinas que más velocidad necesitan en las primeras líneas de programa, reducir el nombre (en longitud) de las variables, etc. Pero al final llegamos a un punto en que no podemos mejorar nuestros programas en cuanto a velocidad.


Lenguaje BASIC y su intérprete.

El editor del intérprete de BASIC


Para muchos, el BASIC del Spectrum es un comienzo prácticamente obligado para programar, pero si queremos realizar programas con la calidad del software comercial no puede ser la herramienta a utilizar. Dejando de lado que sigue siendo una herramienta muy útil para programar en el Spectrum, para muchos llega la hora de dar el siguiente paso.

Para hacer juegos o programas de calidad comercial en el Spectrum, podemos obviar totalmente el lenguaje BASIC excepto por una serie de comandos que nos serán necesarios para cargar en memoria nuestros programas: comandos como CLEAR, LOAD “” SCREEN$, LOAD “” CODE, USR, POKE y DATA pueden ser necesarios en el “CARGADOR BASIC” de nuestro programa.

El cargador BASIC es el pequeño programa en BASIC que el Spectrum y autoejecuta cuando tecleamos LOAD “”, introducimos una cinta y pulsamos PLAY. El Spectrum carga el pequeño programa en BASIC (el “cargador”), y lo ejecuta. En este cargador es donde introduciremos las pocas líneas de BASIC que necesitaremos para lanzar nuestro programa, haciendo por ejemplo cosas como borrar la pantalla (CLS), colocar BASIC por debajo de una posición de memoria para poder disponer del resto de la memoria como libre (CLEAR), cargar desde cinta la pantalla de carga del juego (LOAD “” SCREEN$), y cargar el código ensamblado de nuestro juego (LOAD “” CODE) para, por fin, saltar a la ejecución al mismo (RANDOMIZE USR).

10 REM Cargador BASIC de un juego.
15 REM Carga la pantalla del juego desde cinta
20 REM luego con un POKE oculta el mensaje "Bytes:"
25 REM para que no borre parte de la pantalla de carga.
30 REM Despues carga el codigo del juego
40 REM y con la ultima linea lo ejecuta.
45 CLS
50 CLEAR 32000
60 LOAD "" SCREEN$
70 POKE 23739, 111
80 LOAD "" CODE
90 RANDOMIZE USR 32000

A lo largo del curso iremos viendo los diferentes comandos BASIC utilizados conforme los vayamos necesitando.


Aparte de realizar programas para el intérprete de BASIC existen múltiples alternativas para programar juegos y aplicaciones que expriman al máximo nuestra máquina:


Para empezar, como primera opción, podemos realizar pequeñas rutinas en ensamblador y utilizarlas desde nuestros programas en BASIC. Programar rutinas en ensamblador y utilizarlas después desde programas en BASIC seguiría el siguiente ciclo de desarrollo:


Primero, programamos una o más rutinas en lenguaje ensamblador, de forma que cada una de estas rutinas realice una función concreta: por ejemplo, dibujar el personaje o enemigos de nuestro juego, borrar la pantalla, actualizar los marcadores, etc.

Ensamblamos el código de las rutinas con un programa ensamblador y obtenemos un bloque de datos “binario” que contiene la traducción del programa que hemos escrito a código máquina directamente comprensible por el microprocesador.

Ahora tenemos 2 opciones para utilizar ese “código máquina” en nuestro programa BASIC.

1.- Si el código máquina resultante es pequeño, porque por ejemplo sólo hemos desarrollado una rutina y apenas ocupa unos pocos bytes, podemos introducir los valores del binario obtenido en nuestro programa BASIC con DATA y POKEarlos en memoria en la dirección deseada. Pongamos por ejemplo que pokeamos esta rutina a partir de la dirección de memoria 40000 (desde 40000 hasta 40000+N siendo N el tamaño del bloque código máquina resultante). Ahora, cuando necesitemos llamar a la rutina en medio de nuestro programa BASIC, lo podremos hacer con un RANDOMIZE USR 40000.

2.- Si por contra el código máquina resultante es grande, porque hemos desarrollado muchas rutinas, pasar estos datos a DATA para POKEarlos es inviable. En ese caso, lo que haríamos sería guardar el bloque de código máquina en cinta justo después de nuestro programa en BASIC. Después, al principio de nuestro programa BASIC cargamos en memoria el bloque de datos de código máquina que va después del mismo en cinta mediante un (por ejemplo) LOAD “” CODE 40000. Una vez tenemos el codigo máquina en memoria, tendremos las diferentes rutinas a partir de la dirección 40000, y podremos utilizar RANDOMIZE USR a la dirección de cada una de ellas en memoria (podríamos por ejemplo tener una rutina de borrado de pantalla en la dirección 40000 y una rutina para dibujar un gráfico en 40100).

Es decir: en ambos casos realizamos una rutina o un conjunto de rutinas en ensamblador y mediante un programa ensamblador, traducimos el código ASM a código que entiende directamente la máquina (código binario) y lo salvamos en cinta (o si es corto, anotamos sus valores para meterlos en DATAs). Después, al inicio de nuestro programa, introducimos ese código binario en memoria de forma que lo podamos llamar en cualquier momento desde BASIC con RANDOMIZE USR.

Esto permite realizar rutinas importantes y críticas en lenguaje ensamblador, y mantener el esqueleto del programa principal en BASIC. Las rutinas creadas en ensamblador son llamadas desde BASIC con la instrucción USR (RANDOMIZE USR x, PRINT USR x o LET A=USR x) en aquellos puntos del programa en que las necesitemos.

Más adelante en este capítulo veremos un ejemplo de cómo realizar el ensamblado de una rutina en ensamblador, su carga en memoria y su utilización desde un programa en BASIC.


Aunque utilicemos rutinas en ensamblador llamadas desde BASIC, seguiremos lastrados por la velocidad del intérprete y los tiempos de ejecución de las partes del programa que no están escritas en ensamblador.

Como una segunda opción alternativa a la integración BASIC-ASM, tenemos la opción de utilizar un compilador de BASIC para compilar nuestros programas y traducirlos a código máquina sin pasar por ningún intérprete de BASIC.

Mediante un compilador de BASIC, a partir de un programa de código fuente en BASIC obtenemos un ejecutable que podremos cargar directamente en memoria y ejecutarlo sin necesidad de utilizar el intérprete del sistema.

La labor de interpretación del código BASIC se hace igualmente, pero se hace antes, ya que en lugar de ejecutar, el resultado de la interpretación se graba ya “traducido” a código máquina en cinta. Un programa en BASIC compilado y ejecutado de este modo es muchísimo más rápido que el mismo programa ejecutado en el intérprete de BASIC del Spectrum.

MCODER, uno de los compiladores nativos de BASIC más conocidos, fue una buena solución en su momento. La compañía DINAMIC realizó algunos de sus primeros juegos en BASIC con MCODER: hablamos de Babaliba, Saimazoom, o la utilidad Artist. MCODER tiene unas limitaciones que no tienen porqué ser especialmente problemáticas si las conocemos, las aceptamos, y realizamos nuestros programas teniéndolas en cuenta. Por ejemplo, no podemos utilizar vectores (creados con DIM en BASIC), y el manejo de cadenas sufre algunos cambios de sintaxis, entre otros.

La principal desventaja de MCODER es que es un compilador BASIC nativo, es decir, que es software para Spectrum que debemos ejecutar dentro de un emulador o la máquina real lo que nos puede ralentizar a la hora de programar.

Una opción mucho más aconsejable es la de utilizar un compilador cruzado como ZX Basic Compiler (ZXB Compiler, de Boriel).

Un compilador cruzado es un compilador que se ejecuta en una plataforma diferente de la plataforma destino, pero genera código para ésta. Por ejemplo, podemos escribir nuestro programa BASIC en un editor de textos en un PC (fuera del Spectrum), compilarlo con un compilador cruzado, y obtener un binario con código máquina de Spectrum, listo para ser ejecutado en un emulador o en una máquina real. De esta forma nos beneficiamos de las mayores capacidades de nuestra plataforma de desarrollo (un PC) para conseguir código compilado para un Spectrum.

En este caso, el compilador cruzado ZX Basic Compiler permite compilar programas escritos en un BASIC con mejoras y generar un programa mucho más eficiente que el que generaría MCODER. Además, ZX Basic incluye bibliotecas de funciones que nos serán muy útiles para realizar programas y juegos de una calidad muy profesional, directamente en BASIC.

El ciclo de desarrollo para la compilación de programas BASIC con un compilador cruzado sería similar al siguiente:


  • Programamos nuestro juego en lenguaje BASIC (siguiendo las reglas especiales que lo diferencien del BASIC estándar del Spectrum) escribiendo el programa en un editor de textos estándar de nuestra plataforma de desarrollo. Para ello utilizaremos uno o más ficheros .BAS.
  • Mediante el compilador cruzado, compilamos los ficheros .BAS y obtenemos un fichero binario de código máquina, normalmente con un cargador BASIC incluído al principio del mismo.
  • Cargamos ese código máquina en nuestro Spectrum o emulador con un simple LOAD “” y el programa se carga y ejecuta como cualquier otro juego comercial.


Es una opción muy interesante para quien quiera seguir programando en BASIC y obtener la potencia que el intérprete de BASIC del Spectrum le resta. Para este caso de uso, ZX Basic es una excelentísima herramienta que puede producir resultados espectaculares, con una comunidad detrás que crea librerías de funciones para que podamos hacer programas o juegos de calidad comercial.


Otra opción es la de aprender lenguaje C y realizar programas íntegramente en C que son compilados (al igual que hace ZX Basic Compiler) y trasladados a código binario que ejecutará el Spectrum.

Podemos ver el lenguaje C (en el Spectrum) como una manera de realizar programas bastante rápidos saltándonos las limitaciones de BASIC. No llega a ser ensamblador, pero desde luego es mucho más rápido que BASIC (y más que BASIC compilado con MCODER).

C es un lenguaje muy potente y de alto nivel, y el compilador cruzado existente para Spectrum (Z88DK) genera un código bastante óptimo y cuyos binarios tienen una velocidad de ejecución muchísimo más cercana a la de programas en ensamblador que a la de programas BASIC interpretados.

El desarrollo de un juego o programa en C se realizaría de forma similar al caso de los compiladores BASIC:


  • Programamos nuestro juego en lenguaje C escribiendo el programa en un editor de textos estándar de nuestra plataforma de desarrollo. Escribiermos por tanto el código de nuestro programa como uno o varios ficheros .C, con sus ficheros de cabecera .H.
  • Mediante el compilador cruzado, compilamos los ficheros .C y obtenemos un fichero binario de código máquina, normalmente con un cargador BASIC incluído al principio del mismo.
  • Cargamos ese código máquina en nuestro Spectrum o emulador con un simple LOAD “” y el programa se carga y ejecuta como cualquier otro juego comercial.


Para quien ya conozca el lenguaje C y se desenvuelva bien con él, utilizar un compilador cruzado será sin duda un gran opción. Programando en C se puede hacer prácticamente cualquier aplicación y un gran número de juegos.

Además, se puede combinar ensamblador y C en el mismo programa, con lo cual se puede decir que no estamos limitados por el lenguaje C a la hora de realizar tareas que requieren un control muy preciso de la máquina. Por un lado, Z88DK nos permite embeber código ensamblador dentro de las rutinas en C, y por otro, podemos crear bibliotecas de funciones en ASM puro, enlazarlas junto a nuestro programa, y llamarlas desde el código en C.


Finalmente, la última opción: nos hemos decidido y queremos escribir programas directamente en el lenguaje que comprende la máquina, ya que queremos controlar todo lo que realiza el microprocesador.

Con la opción que hemos elegido, escribiremos el código del programa íntegramente en lenguaje ensamblador (assembler language en inglés, o ASM para abreviar). Como veremos, el lenguaje ensamblador no es un lenguaje de alto nivel como BASIC o C, con instrucciones comprensibles por los humanos (PRINT, FOR, etc) sino que utiliza instrucciones de bajo nivel más cercanas a las acciones individuales capaz de realizar el procesador (LD A, 10, DJNZ bucle, XOR C, etc.).

Con BASIC compilado y con C, es el compilador quien transforma cada comando en múltiples instrucciones en código máquina. En el lenguaje ensamblador, la “compilación” (conocida como proceso de ensamblado) del programa en código máquina es una mera traducción ya que cada instrucción en ensamblador se traduce en una instrucción en código máquina.

Para programar en ensamblador seguiremos el siguiente proceso:


  • Programamos nuestro juego en lenguaje ensamblador escribiendo el programa en un editor de textos estándar de nuestra plataforma de desarrollo. Escribiremos por tanto el código de nuestro programa como uno o varios ficheros .ASM.
  • Mediante el ensamblador cruzado, ensamblamos los ficheros .ASM y obtenemos un fichero binario de código máquina, normalmente con un cargador BASIC incluído al principio del mismo.
  • Cargamos ese código máquina en nuestro Spectrum o emulador con un simple LOAD “” y el programa se carga y ejecuta como cualquier otro juego comercial.


Es importante destacar que el desarrollo de un programa en ASM requiere mucho más tiempo, un mejor diseño y muchos más conocimientos del hardware que utilizar cualquier otro lenguaje. Un programa en BASIC sencillo puede tener 1000 líneas, pero el mismo programa en ASM puede tener perfectamente 10000, 50000, o muchas más líneas.

En ensamblador no tenemos funciones de alto nivel que realicen determinadas tareas por nosotros: no existe PRINT para imprimir cosas por pantalla, si queremos imprimir texto tenemos que imprimir una a una las letras, calculando posiciones, píxeles, colores, y escribiendo en la videomemoria nosotros mismos. Podemos apoyarnos en una serie de rutinas que hay en la ROM del Spectrum (que son las que utiliza BASIC), pero en general, para la mayoría de las tareas, lo tendremos que hacer todo manualmente.

Un ejemplo muy sencillo: en BASIC podemos multiplicar 2 números de forma muy simple con el operador *. En ensamblador, no existe un comando para multiplicar 2 números. No existe dicho comando porque el micro Z80 tiene definida la operación de suma (ADD) y la de resta (SUB), por ejemplo, pero no tiene ninguna instrucción para multiplicar o dividir. Y si queremos multiplicar 2 números, tendremos que hacer una rutina en ensamblador que lo haga (por ejemplo, realizando la multiplicación en base a múltiples sumas) y llamarla cada vez que necesitemos realizar una multiplicación.

; Rutina de multiplicación en lenguaje ensamblador:
;
; Mult_HL_DE: Multiplica DE*BC
; Entrada:   DE: Multiplicando,
;            BC: Multiplicador
; Salida:    HL: Resultado.
; Modifica:  AF, BC 
 
Mult_HL_DE:
    ld hl, 0                  ; HL = 0
 
multhlde_loop:
    add hl, de                ; Sumamos HL = HL + DE
    dec bc
    ld a, b
    or c
    jr nz, multhlde_loop      ; Lo repetimos BC veces
    ret                       ; Volver de la rutina

Es posible que el anterior párrafo parezca demasiado “duro” para los programadores acostumbrados a BASIC y que lo anteriormente explicado parezca un panorama desolador, pero esa es la realidad con el ensamblador: cada instrucción en ensamblador se corresponde con una instrucción de la CPU Z80. Si se quiere hacer algo más complejo que lo que permite directamente la CPU, nos lo hemos de construir nosotros mismos a base de utilizar esas instrucciones. Una multiplicación se puede realizar como una serie de sumas, por ejemplo, como hemos visto en la rutina MULT del apartado anterior.

Obviamente, no tendremos que escribir miles de rutinas antes de poder programar cualquier cosa: existen rutinas ya disponibles que podemos aprovechar. En Internet, en revistas Microhobby, en libros de programación de Z80, en la ROM del Spectrum, encontraremos rutinas listas para utilizar y que nos permitirán multiplicar, dividir, imprimir cadenas de texto, y muchas otras cosas.

Además, cada nueva rutina que programemos podremos reutilizarla en futuros programas, por lo que el inicio es duro pero a partir de cierto momento dispondremos de bibliotecas de rutinas reutilizables que podremos integrar en nuestros programas para reducir el tiempo de desarrollo.


Está claro que cada lenguaje tiene su campo de aplicación, y podría ser perfectamente aceptable utilizar BASIC para hacer una herramienta interactiva para el usuario (con mucho tratamiento de textos) o bien para hacer un programa basado en texto, o una pequeña base de datos.

Donde realmente tiene interés la programación en lenguaje ensamblador es en la creación de determinadas rutinas, programas o juegos orientados a exprimir el hardware de la máquina, es decir: aquellos programas orientados a escribir rápidamente gráficos en pantalla, reproducir música, o controlar el teclado con gran precisión. Nos estamos refiriendo principalmente a los juegos.

Ensamblador es el lenguaje ideal para programar juegos que requieran gran velocidad de ejecución. Como veremos en el futuro, dibujar en pantalla se reduce a escribir valores en memoria (en una zona concreta de la memoria). Leer del teclado se reduce a leer los valores que hay en determinados puertos de entrada/salida de la CPU, y la reproducción de música se realiza mediante escrituras en otros puertos. Para realizar esto se requiere mucha sincronización y un control total de la máquina, y esto es lo que nos ofrece ensamblador.

Este curso está diseñado con los siguientes objetivos en mente:


  • Conocer el hardware del Spectrum, y cómo funciona internamente.
  • Conocer el juego de instrucciones del microprocesador Z80 que lleva el Spectrum.
  • Saber realizar programas en lenguaje ASM (ensamblador) del Z80.
  • Aprender a realizar pequeñas rutinas que hagan tareas determinadas y que sean después reutilizables desde otros programas o desde BASIC.
  • Con la práctica, ser capaces de escribir un juego o programa entero en ASM.


Proporcionaremos al lector todos los conceptos necesarios para conseguir estos objetivos. El resto lo aportará el tiempo que nos impliquemos y la experiencia que vayamos adoptando programando en ensamblador. No se puede escribir un juego completo en ensamblador la primera vez que uno se acerca a este lenguaje, pero sí que puede uno realizar una pequeña rutina que haga una tarea concreta en un pequeño programa BASIC. La segunda vez, en lugar de una pequeña rutina hará un conjunto de rutinas para un juego mayor, y, con la práctica, el dominio del lenguaje se puede convertir para muchos en una manera diferente o mejor de programar: directamente en ensamblador.

Como hemos comentado anteriormente, programar en ensamblador no es fácil. Este curso deberían seguirlo aquellas personas con ciertos conocimientos sobre programación que se sientan preparadas para dar el paso al lenguaje ensamblador. Un requerimiento imprescindible es que el lector debe de conocer fundamentos básicos del sistema de codificación decimal, hexadecimal y binario. Como ya sabéis, nosotros expresamos los números en base decimal (base 10), pero esos mismos números se pueden expresar también en otras bases, como hexadecimal (base 16), o en binario (base 2). Son diferentes formas de representar el mismo número, y para distinguir unas formas de otras, tanto en el código como en las explicaciones teóricas se colocan prefijos o sufijos que nos indican la base utilizada. A lo largo del curso se utilizarán las siguientes convenciones de prefijo o sufijo de formato:

Prefijo Tipo de dato
$ Valor hexadecimal
% Valor en binario
Ninguno Valor en decimal
Sufijo Tipo de dato
h Valor hexadecimal
b Valor en binario
Ninguno o d Valor en decimal

Por ejemplo:

DECIMAL HEXADECIMAL BINARIO
64d ó 64 $40 ó 40h %01000000 ó 01000000b
255d ó 255 $FF ó FFh %11111111 ó 11111111b
3d ó 3 $03 ó 03h %00000011 ó 00000011b

Para seguir el curso es muy importante que el lector sepa distinguir unas bases de codificación de otras y que sepa (con más o menos facilidad) pasar números de una base a otra.


Aunque nuestro objetivo final sea desarrollar un programa o juego para la máquina real, el testear cada cambio, cada prueba o cada mejora en un equipo Spectrum físico es algo que requeriría tanto tiempo que alargaría el desarrollo de cualquier cosa a tiempos que a día de hoy nos parecían absurdos. Ensamblar, pasar el binario a cinta y llevarlo al Spectrum es lento y engorroso. Otra opción sería pasar el TAP resultante a una SD y así probarlo más rápidamente en un Spectrum que tenga un dispositivo DivIDE o Dandanator, pero el baile de copias y pruebas cada vez que queramos probar un cambio requeriría una ingente cantidad de tiempo.

En la época de los 80, los programadores “amateur” (y a veces, los profesionales) tenían que programar con ensambladores en el Spectrum real, tecleando el código en su poco ergonómico teclado y guardando los datos en cinta después de ensamblar, en una especie de puzzle de rutinas en cinta que podía acabar (ante cualquier fallo en el programa) con un cuelgue o reseteo del Spectrum y la pérdida de todo lo tecleado.

Los programadores más profesionales tenían a su disposición otros sistemas (como PCs) con entornos de desarrollo en los cuales programaban y podían pasar los binarios resultantes para probarlos en los equipos físicos mediante cables específicos para ello.

En nuestro caso, disponiendo de emuladores es inconcebible y absurdo no utilizarlos para testear el código resultante. Editar un fichero, ensamblar, obtener un TAP, hacer doble click sobre él y probarlo en un emulador, en apenas segundos, es una ventaja de un valor incalculable, de la que no gozaron los programadores de los juegos de Spectrum de la época (y que da más mérito aún a sus creaciones).

Los emuladores no sólo nos permiten probar nuestros cambios rápidamente, sino que nos pueden proporcionar herramientas de desarrollo útiles.

Por ejemplo, (por citar sólo dos de ellos) tanto FUSE -Free UNIX Spectrum Emulator- (en Linux, Windows y Mac), como ZX Spin (en Windows) tienen integrado un debugger o depurador que nos permitirá ejecutar nuestros programas paso a paso.

Un debugger es una herramienta que nos permite ver el contenido de los registros del Z80, la posición del “puntero de ejecución” (PC, de Program Counter o Contador de Programa), qué hay en la memoria, y ejecutar instrucciones una a una, paso a paso, y ver qué resultado y cambios producen. El debugger de ZX Spin, accesible en “Tools > Debugger” tiene el siguiente aspecto:


El utilísimo debugger de Spin

El utilísimo debugger de Spin


Y el Debugger de FUSE en su versión GTK, accesible desde Machine > Debugger nos mostrará la siguiente ventana:


El debugger de FUSE

El debugger de FUSE


En ambos casos podemos ver los valores de los registros del Z80, el contenido de la memoria, el equivalente en ensamblador del código máquina en memoria, y controles para avanzar la ejecución paso a paso, o de poner “puntos de interrupción” (breakpoints) y proseguir la ejecución del programa hasta que la ejecución llegue a ese punto (en que se detendrá para que podamos continuar paso a paso, algo perfecto para estudiar cómo se comportan nuestras rutinas).

En este sentido ZX Spin es más sencillo de utilizar porque se hace todo con un interfaz gráfico de ventanas mientras que el debugger de FUSE para ciertas tareas (como establecer breakpoints), funciona por comandos de texto que se introducen en una caja en la parte inferior de la pantalla.

FUSE incorpora también una ventana con un “memory browser” para ver el contenido de cualquier celda de memoria, como también se puede hacer en ZX Spin.


El "memory browser" de FUSE

El “memory browser” de FUSE


ZX Spin tiene incluso un ensamblador integrado que nos permitirá ensamblar programas y ponerlos en memoria directamente desde el emulador, o una opción para cargar bloques de datos binarios desde fichero o guardar porciones de la memoria a fichero, funcionando además bajo Wine en sistemas Linux.

Debuggers” y “Memory Browsers” son herramientas valiosísimas para desarrollar, por lo que recomendamos descargar uno para nuestro Sistema Operativo que tenga al menos esas 2 opciones, y avanzar en el curso haciendo uso de ellas y aprendiendo a manejarlas, ya que es una pequeñísima inversión de tiempo que rentabilizaremos rápidamente (en el Anexo 1 de este curso veremos cómo utilizar el depurador/debugger de Fuse).

FUSE y ZX Spin no son los únicos emuladores que contienen este tipo de herramientas, hemos citado estos porque son “clásicos” (de hecho, varios emuladores nuevos han surgido después de ellos que incorporan muchas más opciones, como ZEsarUX o Spectaculator), pero podemos elegir aquel que mejor conozcamos o que tenga un interfaz más amigable para nosotros.

Eso sí, cada cierto tiempo recomendamos probar el programa en un equipo real, para asegurarnos de que no estamos haciendo nada que sea incompatible con un equipo físico. No resulta nada divertido hacer un desarrollo de varios meses y descubrir que funciona en el emulador pero no en nuestro Spectrum (algo que podría suceder, sobre todo con los primeros emuladores cuya emulación no era 100% fiel, o emuladores que no simulen el “efecto nieve” en ciertas circunstancias del Spectrum), por lo que no es necesario probar cada cambio en un Spectrum real, pero tampoco cuesta nada hacer alguna prueba cada vez que pasemos alguna “meta” en el desarrollo del programa.


  • cursos/ensamblador/introduccion.txt
  • Última modificación: 24-01-2024 12:40
  • por sromero