Instrucciones para operaciones aritméticas (resta)

“sbc” es la instrucción que resta un número (sustraendo) del acumulador (minuendo). La resta la deja en el acumulador.

Igual que en la suma interviene el flag C – carry, en la resta también interviene. Pero de una forma bastante más compleja de entender y de explicar. Vamos a intentarlo.

Ya comentamos en su momento que el microprocesador implementa la resta como una suma, concretamente sumando al acumulador/minuendo el complemento a dos del sustraendo. En principio, esto es un detalle de funcionamiento interno del microprocesador que debería ser “transparente” al programador, pero para entender mejor lo que ocurre y cómo programar, es mejor restar igual que lo hace el microprocesador.

Minuendo mayor que sustraendo:

Como ejemplo, tomemos minuendo = $ff (255) y sustraendo = $f0 (240). El resultado de esta resta debería ser $0f (15). Veamos si es así:

  • $ff = %11111111
  • $f0 = %11110000
  • Complemento de $f0 = %00001111
  • Complemento a dos de $f0 = %00010000
  • Resta $ff – $f0 = Suma $ff + complemento a dos de $f0 = %11111111 + %00010000 = %100001111 = %00001111 + flag C activado = $0f + flag C activado

El resultado es el que cabía esperar: $0f o 15. Y llama la atención el hecho de que el flag C quede activado porque al sumar el complemento a dos se necesitan 9 bits, y sólo se dispone de 8.

Minuendo menor que sustraendo:

Tomemos ahora el caso contrario, minuendo = $f0 (240) y sustraendo = $ff (255). El resultado debería ser -15, es decir, $f1. Veamos si es así:

  • $f0 = %11110000
  • $ff = %11111111
  • Complemento de $ff = %00000000
  • Complemento a dos de $ff = %00000001
  • Resta $f0 – $ff = Suma $f0 + complemento a dos de $ff = %11110000+ %00000001 = %11110001 = $f1 + flag C desactivado

Nuevamente, el resultado es el que cabría esperar: $f1 (que hay que interpretar como -15). Y ahora llama la atención que, al contrario que en el caso anterior, el flag C quede desactivado.

Conclusiones sobre la resta mono-byte:

Cuando el minuendo es mayor que el sustraendo, es decir, cuando la resta es positiva, el flag C se activa. Por el contrario, cuando el minuendo es menor que el sustraendo, es decir, cuando la resta es negativa, el flag C se desactiva.

De hecho, con la resta se hace al revés que con la suma (que primero se debe borrar el acarreo con “clc” y luego se suma con “adc”): primero se debe activar el acarreo con “sec” y luego se resta con “sbc”. Si la resta es positiva, el acarreo seguirá activado después de la resta; si es negativa se habrá desactivado.

Conclusiones sobre la resta multi-byte:

Recordemos que se podía hacer suma multi-byte, y que la instrucción “adc” sumaba acumulador, operando y acarreo precisamente para extender la suma de un byte al siguiente (el “me llevo una” de la suma).

Análogamente, se puede hacer resta multi-byte. Y por lo que se ha visto en el apartado anterior (C activado = resta positiva; C desactivado = resta negativa) el “tomo una” de la resta, es decir, el tomar prestada una unidad del siguiente byte porque si no la resta del byte actual saldría negativa, hay que hacerlo, precisamente, cuando el acarreo está desactivado.

Es por esto que la instrucción “sbc” lo que hace es acumulador – operando – complemento de C. Y esta resta se vuelve a meter en el acumulador.

En fin, complejo de explicar, pero lo hemos intentado…

Modos de direccionamiento y flags:

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

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


Programa de ejemplo: Prog14

Deja un comentario