Instrucciones para operaciones aritméticas (suma)

Las instrucciones para hacer operaciones aritméticas son:

  • “adc”.
  • “sbc”.

La primera instrucción vale para sumar y la segunda para restar.

“adc” es la instrucción que permite sumar un número al acumulador, dejando la suma nuevamente en el acumulador. Y un detalle muy importante es la “c” del final; la instrucción no se llama “add”, se llama “adc”. Esto es así porque en realidad lo que se suma son tres cosas: el acumulador, el operando, y el flag C – carry.

Esto es fuente de muchísimos errores, porque uno hace un programa para sumar el acumulador (supongamos que tiene el valor 10) y otro valor (supongamos que otro 10), y a veces obtiene 20 y otras veces 21, y no se explica por qué. La explicación es el flag C – carry, que a veces vale 0 y a veces vale 1, en función de la situación previa del registro de estado. Para evitar esto, siempre hay que preceder toda (o casi toda) instrucción “adc” con una instrucción “clc”, que lo que hace es borrar el acarreo.

Pero el hecho de sumar el flag C tiene su razón de ser. No está ahí para molestar. Al sumar dos bytes (el acumulador y otro) es posible que la suma exceda la capacidad del acumulador (ej. $ff + $ff = $1fe) y esto se señaliza poniendo el flag C a uno. En cierto modo el flag C nos está señalizando ese “1” extra que tenemos por la izquierda. Pero es que, además, si a uno no le llega con un byte para la suma, lo lógico es que use dos bytes. Y aquí es donde entra el acarreo: en la suma multi-byte.

Para sumar dos sumandos de dos bytes, lo que hay que hacer es:

  • Borrar el acarreo que pudiera venir heredado de antes (“clc”), para que así no moleste.
  • Sumar los bytes menos significativos de ambos sumandos. Uno tendrá que estar en el acumulador, y el otro estará en memoria según el modo de direccionamiento que se utilice. También se sumará el acarreo (“adc”), pero ya hemos dicho que lo habremos puesto a cero. El resultado se llevará al byte menos significativo de la suma.
  • Sumar los bytes más significativos de ambos sumandos. Nuevamente, uno tendrá que estar en el acumulador. Y también se sumará el acarreo derivado de la suma de los bytes menos significativos (“adc”). El resultado se llevará al byte más significativo de la suma.

Obsérvese que entre la suma de los bytes menos significativos y la suma de los bytes más significativos no se borra el acarreo (“clc”). Esto es deliberado; interesa tener en cuenta ese acarreo para que la suma sea correcta.

El procedimiento anterior se puede generalizar fácilmente a N bytes. Y ahora se le ve la razón de ser al acarreo: no sólo señalizar un desbordamiento de capacidad; también facilitar la suma multi-byte.

La instrucción “adc” soporta muchos modos de direccionamiento: inmediato, absoluto, página cero, absoluto indexado, página cero indexado, indirecto – indexado e indexado – indirecto. Y afecta a los flags: S – sign, V – overflow, Z – zero y C – carry.

Además, debe tenerse en cuenta que las reglas de la suma no son las mismas si se está usando codificación binaria (lo más habitual) o si se está usando codificación BCD (menos habitual). En el segundo caso habrá que informar al microprocesador mediante la instrucción “sed”.

Los detalles de esta instrucción se pueden consultar en http://www.6502.org/tutorials/6502opcodes.html#ADC.


Programa de ejemplo: Prog13

Deja un comentario