3.4.1 SUMA, RESTA Y COMPARACIÓN
SUMA SIN ACARREO:
Consiste en sumar al contenido del registro "A" un número y obtener el resultado en el registro "A". El indicador de acarreo no se tiene en cuenta para esta operación. Su esquema sería:
|
SUMA CON ACARREO:
Exactamente igual que la anterior, pero se suma también el indicador de acarreo del registro "F". De esta forma, sepuede incluir en la suma el acarreo procedente de una suma anterior. Su esquema sería:
|
RESTA SIN ACARREO:
Consiste en restar un número del contenido del registro "A", y obtener el resultado en este mismo registro. El indicador de acarreo no interviene en la operación. Se consideran números negativos los superiores a 127 (7Fh) de la forma que se explicó en el capítulo relativo a los sistemas de numeración; es decir, el número 255 (FFh) se considera "-1", el 254 (FEh) se considera "-2" y así sucesivamente, hasta 128 (80h) que se considera "-128". El paso de 127 a 128 o viceversa se indica poniendo a "1" el flag de "overflow" (P/V) del registro "F". Su esquema sería:
|
RESTA CON ACARREO:
Igual que el anterior, salvo que también se resta el indicador de acarreo (CF) del registro "F". Su esquema sería:
|
INCREMENTO:
Consiste en sumar uno al contenido de un registro que se especifica en la instrucción. Su esquema es:
|
Donde "R" representa un registro cualquiera de 8 a 16 bits. Si se trata de un registro doble (de 16 bits) se incrementa el registro de orden bajo (por ejemplo, en el "BC" se incrementa "C"), y si ello hace que este pase a valer "0", se incrementa también el de orden alto.
DECREMENTO:
Es la inversa de la anterior, consiste en restar uno al contenido de un registro. Su esquema es:
|
Si se trata de un registro doble, se decrementa el de orden bajo y, si esto hace que pase a valer 255 (FFh), se decrementa también el de orden alto.
Si el registro incrementado o decrementado es de 8 bits, resultan afectados los indicadores del registro "F".
GRUPO ARITMETICO DE 8 BITS (SUMA Y RESTA |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Tabla de codificación para suma y resta. |
Al igual que en el capítulo anterior, vamos a hacer algunos programas en código máquina que nos demuestren el funcionamiento de las instrucciones de suma y resta. Al mismo tiempo, iremos cogiendo práctica en la realización y ensamblado de programas en Assembler.
Recomendamos al lector que no se limite a «leer por encima» este curso. Si desea, de verdad, aprender a programar en código máquina, debe seguir el curso encima de una mesa con lápiz y papel en la mano. Intente ensamblar cada programa usted mismo y no se limite a ver cómo lo hacemos nosotros; e incluso, atrévase a escribir sis propias rutinas. No se preocupe si el ordenador se le «cuelga» cincuenta veces, es totalmente normal, una rutina en código máquina rara vez funciona a la primera.
Vamos con el primero de nuestros programas. Se trata de sumar dos números sin acarreo. Utilizaremos un programa en Basic que se encargará de gestionar la entrada de datos, llamar a la rutina en C/M e imprimir los resultados, pero la suma la realizaremos en código máquina.
En principio, necesitamos POKEar los dos números que vamos a sumar en dos direcciones de memoria, desde donde serán leidos por la rutina C/M. Estas dos direcciones serán la 5CB0h (23728) para el primer operando, y la 5CB1h (23729) para el segundo; estas direcciones corresponden a una variable del sistema que no se usa.
Primero escribiremos el programa en C/M y luego el Basic. En Assembler, nuestra rutina podría ser algo así:
|
Las líneas 10, 20 y 30 leen los dos operandos desde las posiciones de memoria donde los almacenó el Basic. La línea 40 realizará la suma equivalente a:
|
Las líneas 50 y 60 transfieren el resultado al registro "B" y los indicadores de estado del registro "F", al registro "C". Recuerde que el registro "BC" es lo que nos devuelve USR cuando retornamos a Basic. Mirando las tablas de codificación, podemos ensamblar el programa:
|
Habría sido interesante que el propio lector hubiera ensamblado el programa antes de mirar la tabla anterior. Prométase a sí mismo que la próxima vez lo intentará.
Ya tenemos preparada la rutina en código máquina para sumar dos números. Seamos buenos con los que aún tienen solo 16K, y carguemos la rutina a partir de la dirección 31000.
Ha llegado el momento de pasar al olvidado Basic. El PROGRAMA 1 se encarga de todo. La línea 10 baja RAMTOP, las líneas 20 y 30 introducen en memoria nuestra rutina que se encuentra en los DATA de la línea 40. Las líneas 50 a 100 nos piden los dos operandos y los POKEan en memoria tras comprobar si están dentro de rango.
|
|||
PROGRAMA 1. |
[Fichero TAP] |
La línea 110 llama a nuestra rutina en C/M de forma que, al retornar, el contenido del registro "BC" se almacena en la variable "a". En 120 llamamos a la rutina 3100 que nos pasa el número a binario, esta subrutina es la mism que usábamos en el programa para cambiar de base, del capítulo 3. Las líneas 130 y 140 completan el número con ceros a la izquierda para obtener, de nuevo, 16 bits. Finalmente, las líneas 200 a 220 imprimen en pantalla el valor que contenía el acumulador después de efectuar la suma y el estado de los indicadores en el registro "F". El significado de los indicadores es el siguiente:
|
Los indicadores marcados "x" presentan un estado indeterminado y no habrá que tomarlos en cuenta.
Una vez que tenga el programa en memoria, pruebe a introducir distintos operandos comprendidos entre 0 y 255. Le sugerimos unos cuantos:
|
Puede utilizar este mismo programa para la resta cambiando "ADD A,B" por "SUB A,B", es decir, el "128" de la línea 40 por un "144". Haga el cambio y ejecute el programa de nuevo, esta vez restará el segundo operando del primero. Si el segundo operando es mayor que el primero (resultado negativo) el indicador "C" se pondrá a "1" y el resultado aparecerá en complemento a 2.
Ahora vamos a complicar un poco más la cosa, se trata de hacer una rutina qeu permita sumar números superiores a 255. En este caso, usaremos la instrucción "ADC" (sumar con acarreo) para poder tener en cuenta, cuando sumemos un octeto, el acarreo procedente del anterior.
Introduciremos el primer operando en las posiciones 5CB0h (23728) y 5CB1h (23729) (primero el octeto menos significativo y luego el más significativo), y el segundo operando en 5C76h (23670) y 5C77h (23677).
El programa en Assembler puede ser algo como:
|
La línea 10 pone a «cero» el indicador de acarreo; se trata de un pequeño "truco" que consiste en realizar un "AND" lógico del acumulador consigo mismo, con lo que el contenido no varía, pero se pone a cero el indicador de acarreo. Más adelante, y dentro de este mismo capítulo, veremos las operaciones lógicas.
Las líneas 20, 30 y 40 cargan los octetos de orden bajo de los dos operandos. La línea 50 los opera (suma) y, si hay acarreo, lo guarda para la suma siguiente. La línea 60 guarda el resultado en "C" (octeto bajo de "BC").
La operación se vuelve a repetir para los octetos altos; las líneas 70, 80 y 90 cargan los operandos. La línea 100 los suma tomando en cuenta el acarreo procedente de la operación anterior. Finalmente, la línea 110 transfiere el resultado al registro "B" (octeto alto de "BC").
La operación ya se ha realizado, tenemos el resultado en "BC" y, por tanto, será lo que obtengamos al retornar a Basic. Ahora sólo nos falta sacar, de alguna forma, el contenido del registro "F" (indicadores) de forma que lo podamos leer desde Basic. Para ello, las líneas 120 y 130 pasan los contenidos de "A" y "F" a "DE" y la línea 140 almacena el contenido de "E" en la posición de memoria 5CB0h (23728), desde donde será leido por el Basic. En esta operación, también se guarda en 23729 el contenido del registro "D" pero, en este caso, no nos interesa.
Sería interesante que el lector intentara, ahora ensamblar por su cuenta este programa, para ello, deberá proceder como hicimos nosotros en el caso anterior. Primero, copie el programa en un papel, ahora, vaya buscando cada instrucción en las tablas ("AND A" se ensambla como A7h ó 167d). A continuación, escriba los operandos numéricos sin olvidar invertir el orden de los octetos y finalmente, acuérdese de ensamblar "RET" como C9h o 201d.
¿Ya lo tiene? Correcto, ahora compruebe si lo que ustes ha ensamblado coincide con lo nuestro.
|
No se preocupe si se ha equivocado en algo, sería mucho pedir que el primer programa que ensambla le saliera sin errores. Ahora, con los datos de la tercera columna (donde dice: "Decimal") podemos construir el programa en Basic que introduzca esta rutina en memoria, y la utilice para sumar dos números. Este programa es el listado que aparece con el nombre de PROGRAMA 2. No hace falta que lo copie entero, si lo desea, puede cargar el PROGRAMA 1 y reescribir las líneas 20, 40, 60, 70, 90, 100, 110, 120, 130, 210 y 220 ya que son las únicas que varían.