Capítulo 9 - Programando Bit a Bit

En el mundo de la programación de computadores, realizar operaciones binarias en un solo bit es algo parecido a hacer microcirugía. Si es capaz de comprobar bits, desplazar y, en general manipular bits con habilidad, entonces usted es un verdadero D.P.E. (Doctor de Programación en lenguaje Ensamblador). Sin embargo, la manipulación de bits, como la mayoría de las facetas de la programación en lenguaje ensamblador, no es tan difícil como parece a primera vista. La comprensión de algunos principios básicos eliminará gran parte del misterio del desplazamiento, comprobación y otras operaciones de un solo bit en lenguaje ensamblador. Ya hemos visto muchos de los conceptos que necesita saber para convertirse en un cirujano experto en bits.



Por ejemplo, considere lo que ya ha aprendido sobre el uso del bit de acarreo del registro de estado del procesador del 6502. El uso el bit de acarreo es una de las técnicas de manipulación de bits más importantes en el lenguaje ensamblador del 6502. Ya tiene un poco de experiencia en el uso del bit de acarreo, esto lo vio en los programas de sumas. En este capítulo, tendrá la oportunidad de enseñarle a su computador cómo realizar algunos trucos nuevos utilizando el bit de acarreo del registro de estado (P) del procesador 6502.


Usando el bit de acarreo en Operaciones de desplazamiento de bits («Bit-Shifting»)


Como hemos señalado en varias ocasiones, el microprocesador 6502 de su computador Atari es un chip de 8 bits: no puede realizar operaciones con números mayores a 255 sin tener que hacer algunas contorsiones un poco tortuosas. Con el fin de procesar números mayores a 255, el 6502 debe dividirlos en trozos de 8-bits, y luego realizar las operaciones requeridas en cada trozo del número. Después, cada trozo del número debe volver a juntarse. Una vez que esté familiarizado y sepa cómo se hace esto, verá que no es tan difícil como parece. De hecho la tijera electrónica que se utiliza en todas estas operaciones electrónicas de cortar y pegar en realidad es un solo bit, el bit de acarreo en el registro de estado (P) del procesador 6502.


Cuatro instrucciones de desplazamiento de bits


Ya ha visto cómo funcionan las operaciones de acarreo en varios programas de este libro. Pero para aclarar cómo funciona el acarreo en la aritmética del 6502, será útil examinar en detalle cuatro instrucciones muy especializadas del lenguaje de máquina: ASL («Arithmetic Shift Left – desplazamiento aritmético a la izquierda»), LSR («Logical Shift Right – Desplazamiento lógico a la derecha»), ROL («ROtate Left – Rotar a la izquierda»), y ROR («ROtate Right – Rotar a la derecha»). Estas cuatro instrucciones son usadas ampliamente en el lenguaje ensamblador del 6502. Nos ocuparemos de cada uno de ellos, comenzando con la instrucción ASL (Desplazamiento aritmético a la izquierda).


ASL (Desplazamiento aritmético a la izquierda)


Como señalamos anteriormente en el capítulo sobre la aritmética binaria, cada número redondo (terminado en uno o más ceros) en notación binaria es igual al cuadrado de número binario redondo anterior. En otras palabras, 1000 000 ($80) es el doble del número 0100 000 ($40), que es el doble del número 0010 0000 ($20), que es el doble del número 0001 0000 ($ 10), y así sucesivamente. Por lo tanto, es muy fácil de multiplicar un número binario por 2. Todo lo que tiene que hacer es desplazar cada bit del número una posición a la izquierda, y colocar un cero en el bit que ha quedado vacío a causa de este desplazamiento, que es el bit 0, o el bit de más a la derecha del número. Si el bit más a la izquierda (bit 7) del número que se quiere multiplicar por 2 es un 1, entonces es necesario un acarreo. Toda esta operación que acabamos de describir, desplazar un byte a la izquierda y con acarreo, se puede realizar con una sola instrucción en 6502 en lenguaje ensamblador. Esta instrucción es ASL, que significa «Arithmetic Shift Left – Desplazamiento aritmético a la izquierda». He aquí un ejemplo de cómo funciona la instrucción ASL:



Como puede ver en la ilustración, la instrucción ASL mueve cada bit de un número de 8 bits un espacio a la izquierda, excepto el Bit 7. El Bit 7 'cae' en el bit de acarreo del registro de estados del procesador (P). La instrucción ASL se utiliza para muchos propósitos en el lenguaje ensamblador del 6502. Puede utilizarlo como una manera fácil de multiplicar un número por dos.


      10 ;
      20  *=$0600
      30 ;
      40  LDA #$40; REM 0100 0000
      50  ASL A; SHIFT VALUE IN ACCUMULATOR TO LEFT
      60  STA $CB
      70  .END	

Si ejecuta este programa, y luego usa el comando «D» (“display – desplegar”) del depurador para examinar el contenido de la posición de memoria $CB, verá que el número $40 90100 0000 ha sido multiplicado por dos (quedando en $80 (1000 0000)) antes de ser almacenado en la dirección de memoria $CB.


Compresión de datos mediante el uso de ASL


Otro uso que tiene la instrucción ASL es la «compresión» de datos, y por lo tanto el aumento de la capacidad de memoria efectiva de un computador. Para tener una idea de cómo funciona la compresión de datos, supongamos que tiene una serie de valores de 4 bytes almacenados en un bloque de memoria en su computador. Estos valores pueden ser caracteres ASCII, números BCD (veremos más acerca de estos números más adelante) o cualquier otro tipo de valores de 4-bits. Utilizando la instrucción ASL, puede comprimir dos valores en un solo byte del bloque de memoria en el que están almacenados. Por lo tanto puede almacenar estos valores en la mitad del espacio de memoria que habrían ocupado en su forma normal sin comprimir. A continuación se presenta una rutina que puede utilizar en un bucle para comprimir cada byte de datos:


      10 ;
      20 ;PROGRAM FOR PACKING DATA
      30 ;
      40  *=$0600
      50 ;
      60 NYB1=$C0
      70 NYB2=$C1
      80 PKDBYT=$C2
      90 ;
      0100  LDA #$04
      0110  STA NYB1
      0120  LDA #$06
      0130  STA NYB2
      0140 ;
      0150  CLC
      0160  LDA NYB1
      0170  ASL A
      0180  ASL A
      0190  ASL A
      0200  ASL A
      0210  ADC NYB2
      0220  STA PKDBYT
      0230  .END	

Cómo funciona la rutina


Esta rutina carga un valor de 4 bits en el acumulador, desplaza ese valor al nibble (sección de 4 bits de un byte) más alto del acumulador, y luego usa la instrucción ADC para colocar otro valor de 4 bits en el nibble más bajo del acumulador. El acumulador queda entonces «empaquetado» con dos valores de 4-bits, y esos dos valores se almacenan en un único registro de memoria de 8 bits.


Comprobando los resultados


Digite el programa en su computadora, y luego use el comando G (“GOTO – ir a”) del MAC/65 o del depurador Atari para ejecutarlo. Entonces, si se ejecuta correctamente, puede usar el comando «D» (display) de su depurador para ver exactamente qué se ha hecho. Con su ensamblador en modo de depuración, digite «DC0» y verá la siguiente línea:


00C0 04 06 46 00 00 00 00 00	

Como se puede ver en esta línea, el programa ha almacenado el número $04 en la dirección de memoria $C0, y $06 en dirección de memoria $C1. Ambos valores han sido comprimidos en la dirección de memoria $C1. No hace falta mucha imaginación para ver cómo esta técnica puede duplicar la capacidad de su computador para almacenar números de 4 bits en posiciones de memoria de 8 bits.


Descompresión de datos


No sería nada bueno comprimir datos si más adelante éstos no pueden ser descomprimidos. Sucede que los datos que han sido comprimidos utilizando ASL pueden ser descomprimidos usando la instrucción complementaria LSR («Logical Shift Right – Desplazamiento lógico a la derecha»). Hablaremos de la instrucción LSR más adelante en este capítulo.


Carga de un registro de color mediante ASL


En el lenguaje ensamblador del Atari, el comando ASL también se puede utilizar para controlar los colores de la pantalla. He aquí cómo puede hacerlo. En un computador Atari los colores que se usan en los gráficos por pantalla se almacenan en cinco registros de color. Las tablas que detallan la lista de los colores y valores de luminancia que pueden ser almacenados en estos registros se encuentran en el capítulo 9 del Manual de referencia del BASIC de Atari. El nibble superior de cada registro de color tiene un valor de color, que es el mismo número que se especifica en el segundo parámetro del comando SETCOLOR del BASIC de Atari. Los bits 1, 2 y 3 de cada registro de color ocupan el valor de luminancia del color, que es el mismo número que se especifica en el tercer parámetro del comando SETCOLOR del BASIC. No importa qué valor tiene el bit 0 de un registro de color, ya que éste no se utiliza. Mediante el uso de la instrucción ASL, se pueden controlar fácilmente los colores que aparecen en pantalla en un programa en lenguaje ensamblador de Atari.


Cómo se hace


El registro de color 2 almacena el color del fondo en Graphics 0, el modo de texto estándar del computador Atari. Suponga que quiere cargar este registro con su color estándar, el cual es azul claro. En su Atari, la dirección de memoria del registro de color 2 es la $02C6. El número de código Atari para el azul es 9, y el número de código para la luminancia del azul claro utilizado en la pantalla GRAPHICS 0 es 4. Por lo tanto se puede usar el comando ASL para almacenar el color azul claro en el Registro de Color 2 de la siguiente manera:


      10 ;
      20 ; SETCLR PROGRAM
      30 ;
      40  *=$0600
      50 ;
      60  CLC
      70  CLD
      80  LDA #$09; REM LIGHT BLUE
      90  ASL A
      0100  ASL A
      0110  ASL A
      0120  ASL A
      0130  STA $02C6; REM COLOR REGISTER 2
      0140  LDA #$04; HUE NO. 4
      0150  ASL A
      0160  ADC $02C6
      0170  STA $02C6
      0180  .END	

Como puede ver, este programa carga el Registro de Color 2 (dirección $ 02C6) con el color #$09, y luminancia #$04, o sea, el color azul claro que Atari utiliza para el fondo de su pantalla estándar de GRAPHICS 0. Si ensamblamos el programa y lo ejecutamos, estos son los valores que quedarán en cada bit del Registro de Color 2 (dirección de memoria $02C6) de su computador.



Probando el Programa


Digite el programa y ejecútelo. Puede utilizar el comando «D» de su depurador MAC/65 o Atari para ver si funciona. Cuando escriba «D26C», échele un vistazo al contenido del Registro de Color 2. La línea en la pantalla debe mostrar que la dirección de memoria $2C6 (Registro de Color 2) contiene el valor $98. Convierta el número hexadecimal $98 a un número binario, y verá que es igual a 10011000, exactamente el mismo número binario indicado anteriormente en nuestro análisis bit por bit del Registro de Color 2. Esta misma técnica se puede utilizar también para cargar cualquier otro registro con cualquier otro color y luminancia en un programa de lenguaje ensamblador. Todo lo que debe hacer es sustituir algunas variables por números literales. He aquí una forma en que el programa podría ser reescrito para que sea más versátil:


Un programa mejor para configurar los colores


      10 ;
      20 ; SETCLR PROGRAM
      30 ;
      40 CLRNR=$C0; COLOR NUMBER
      50 HUENR=$C1; HUE NUMBER
      60 CLREG=$2C6; COLOR REGISTER NR.
      70 ;
      80  *=$0600
      90 ;
      0100  LDA #$09; LIGHT BLUE
      0110  STA CLRNR
      0120  LDA #$04; HUE #4
      0130  STA HUENR
      0140 ;
      0150  CLC ; CLEAR CARRY FLAG
      0160  CLD ; CLEAR DECIMAL FLAG
      0170  LDA CLRNR
      0180  ASL A
      0190  ASL A
      0200  ASL A
      0210  ASL A
      0220  STA CLREG
      0230  LDA HUENR
      0240  ASL A
      0250  ADC CLREG
      0260  STA CLREG
      0270  .END	

Este es en realidad dos programas en uno. De las líneas 100 a la 130, se pueden asignar valores en las variables que representan un color, una luminancia, y un registro de color. Luego, en las líneas de la 150 a la 260 del cuerpo del programa principal, se pueden cargar los valores de color y luminancia en cualquier registro de color. ¿Así que por qué no intentarlo? ¡Cambie las variables que se utilizan en las líneas 40 y 60, ejecute el programa varias veces, y vea cómo cambian los colores de su pantalla!


Una manera más fácil


También puede cambiar los colores de la pantalla sin tomarse la molestia de usar un montón de comandos ASL. Si lo desea, puede realizar todas las operaciones necesarias ASL en su cabeza, antes de escribir el programa. Por ejemplo, si usted multiplica por $ 10 (o 16 en decimal) el número de color Atari, obtendrá el mismo resultado que usted habría realizado con cuatro operaciones ASL sobre el número. Multiplique $09 por $10, y obtendrá $90, el mismo número que se obtendría mediante la utilización de cuatro operaciones ASL sobre el número $09. De manera similar, puede realizar una operación ASL sobre un número binario simplemente multiplicando por 2 (o, si lo prefiere, por $02). Lleve a cabo una operación ASL sobre el número $04 (0100 binario), y obtendrá $08 (1000 binario); el mismo número se obtendría si se multiplica $04 por 2. Si desea escribir un programa similar a SETCLR pero más fácil, puede hacerlo de la siguiente manera:


UN PROGRAMA MÁS FÁCIL QUE SETCLR


      10 ;  
      20 ; AN EASIER SETCLR PROGRAM
      30 ;
      40 CLRNR=$C0 ; COLOR NUMBER
      50 HUENR=$C1 ; HUE NUMBER
      60 CLREG=$2C6 ; COLOR REGISTER NO.
      70 ;
      80  *=$0600
      90 ;
      0100  LDA #$90; COLOR NO. 09 TIMES $10
      0110  STA CLRNR
      0120  LDA #$08 ; HUE NO. 04 TIMES 2
      0130  STA HUENR
      0140 ;
      0150  CLC ; CLEAR CARRY FLAG
      0160  CLD ; CLEAR DECIMAL FLAG
      0170  LDA CLRNR
      0200  STA CLREG
      0230  LDA HUENR
      0250  ADC CLREG
      0260  STA CLREG
      0270  .END	

Al añadir un par de ciclos a un programa como este, además de un bucle infinito, es posible asignar a un registro de color un arco iris de colores en constante cambio. A continuación, puede hacer que el computador Atari dé vueltas una y otra vez en el ciclo, desplegando todos sus colores en la pantalla, sin parar, hasta que se presione la tecla BREAK o SYSTEM RESET, se apague el computador o se tire del enchufe. He aquí un programa que hará esto. Se ejecutará un ciclo sin fin pasando por todos los colores y sus combinaciones que puede generar su Atari, desplegando cada uno de ellos en el área del borde de la pantalla del computador. (Si el programa le parece familiar, es porque lo es. De acuerdo a lo prometido, corresponde a una versión en lenguaje ensamblador del programa de rotación de colores en BASIC que fue presentado en el capítulo 2.)



THE ATARI RAINBOW
RAINBOW.SRC


10 ;  
20 ; RAINBOW.SRC
30 ;
40 COLRBK=$2C8; THE GRAPHICS 0 BORDER COLOR REGISTER
50 TMPCLR=$C0; A PLACE TO STORE COLORS TEMPORARILY
60 ;
70  *=$0600
80 ;
90 START LDA #$FE ; MAX COLOR VALUE
0100  STA TMPCLR
0110 ;
0120 NEWCLR LDA TMPCLR
0130  STA COLRBK
0140 ;
0150  LDX #$FF
0160 LOOPA NOP; JUST A DELAY LOOP
0170 ;
0180  LDY #$30
0190 LOOPB NOP; ANOTHER DELAY LOOP
0200  DEY ; DECREMENT Y REGISTER
0210  BNE LOOPB
0220 ;
0230  DEX ; DECREMENT X REGISTER
0240  BNE LOOPA
0250 ;
0260  DEC TMPCLR ; DCREMENT TMPCLR
0270  DEC TMPCLR ; SUBTRACT 2 FOR NEXT COLOR
0280  BNE NEWCLR ; IF NOT ZERO, CHANGE COLORS AGAIN
0290 ;
0300  JMP START; ALL COLORS DISPLAYED - NOW DO 'EM ALL AGAIN	

LSR (Logical Shift Right – Desplazamiento lógico a la derecha)


La instrucción LSR (Logical Shift Right – Desplazamiento Lógico a la derecha) es el opuesto exacto de la instrucción ASL, como puede observar en esta ilustración:



Una ilustración del mnemotécnico «LSR»


Cómo Funciona la Instrucción LSR


LSR, tal como ASL, trabaja sobre cualquier número binario en el acumulador del 6502. Sin embargo, desplazará cada bit una posición a la derecha. Al bit 7 del nuevo número, que ha quedado vacío producto de la instrucción LSR, se le asignará un cero. El LSB (Least Significant Bit – Bit menos significativo) será asignado a la bandera de acarreo del registro de P. Se puede utilizar la instrucción LSR para dividir por 2 cualquier número par de 8 bits, de la siguiente manera:


DIVIDIR UN NÚMERO POR 2 USANDO LA INSTRUCCION «LSR»
DIV2LSR.SRC


      10 ; DIV2LSR.SRC
      20 ; DIVIDING BY 2 USING LSR
      30 ;
      40 VALUE1=$C0
      50 VALUE2=$C1
      60 ;
      70  *=$0600
      80 ;
      90  LDA #6
      0100  STA VALUE1
      0110 ;
      0120  LDA VALUE1
      0130  LSR A
      0140  STA VALUE2
      0150  .END	

Esta rutina también puede ser utilizada para otro propósito. Si la ejecuta, y luego verifica la bandera de acarreo, podrá identificar si número almacenado en VALUE1 es par o impar. Si la rutina deja el bit de acarreo desactivado, entonces el número que acaba de ser dividido es impar. ¡Si el bit de acarreo está activado, entonces el valor es par!


El siguiente es un programa que puede digitar, ejecutar y comprobar por medio del depurador para ver si un número es par o impar. Si el programa deja el número $FF en la dirección de memoria $C2, cuya etiqueta es FLGADR, entonces el número que fue dividido por 2 en la línea 160 es impar. Si el programa deja un 0 en la dirección FLGADR, entonces el número que se dividió es par:


      10 ; ODDEVEN.SRC
      20 ; ODD OR EVEN?
      30 ;
      40 VALUE1=$C0
      50 VALUE2=$C1
      60 FLGADR=$C2
      70 ;
      80  *=$0600
      90 ;
      0100  LDA #7; (ODD)
      0110  STA VALUE1
      0120  LDA #0
      0130  STA FLGADR; CLEARING FLGADR
      0140 ;
      0150  LDA VALUE1
      0160  LSR A; PERFORM THE DIVISION
      0170  STA VALUE2; DONE
      0180 ;
      0190  BCS FLAG
      0200  RTS; END ROUTINE IF CARRY CLEAR
      0210 ;
      0220 FLAG NOP;
      0230  LDA #$FF; OTHERWISE,SET FLAG
      0240  STA FLGADR
      0250  RTS; ... AND END PROGRAM	

Descomprimiendo los datos


Como hemos mencionado, también puede utilizar LSR para descomprimir datos que han sido comprimidos utilizando ASL. Sin embargo, para descomprimir los datos, también hay que utilizar otro tipo de función en lenguaje ensamblador, llamada operador lógico. Hablaremos de los operadores lógicos y presentaremos una rutina de ejemplo para descomprimir datos más adelante en este capítulo. Mientras tanto, echemos un vistazo a dos operadores de desplazamiento de bits: ROL (que significa «ROtate Left – Rotar a la izquierda») y ROR (que significa «ROtate Right – Rotar a la derecha).


ROL (ROtate Left – Rotar a la izquierda) y ROR (ROtate Right – Rotar a la derecha)


Las instrucciones ROL (rotar a la izquierda) y ROR (rotar a la derecha) también se utilizan para desplazar bits en números binarios. Pero no utilizan uso del bit de acarreo. En su lugar, trabajan de esta manera:



La Instrucción ROL («Rotate Left – Rotar a la izquierda»)



La Instrucción ROR («Rotate Right – Rotar a la derecha»)


Cómo funcionan «ROL» y «ROR»


Como puede ver, ROL y ROR funciona de manera similar a ASL y LSR, salvo que se asigna el bit de acarreo (en lugar de cero) al bit del extremo que quedó vacío producto de la rotación. ROL, tal como ASL, desplaza el contenido de un byte un lugar a la izquierda. Sin embargo, ROL no le asigna un cero al bit 0. En su lugar, asigna el bit de acarreo al bit 0 del número que está siendo desplazo, y que ha quedado vacío producto de la rotación, y asigna el bit 7 al bit de acarreo. ROR funciona igual que ROL, pero en la dirección opuesta. Mueve cada bit de un byte una posición a la derecha, colocando el bit de acarreo en el bit 7 y el bit 0 en el bit de acarreo.


Los operadores lógicos


Antes de pasar a la aritmética binaria convencional, echemos un breve vistazo a cuatro mnemotécnicos importantes del lenguaje ensamblador llamados Operadores Lógicos. Estas instrucciones son AND («y»), OR («o»), EOR ( «exclusive or – o exclusivo (disyunción exclusiva)"), y BIT («bit»). Los cuatro operadores lógicos del 6502 parecen muy misteriosos a primera vista. Pero, típico del lenguaje ensamblador, pierden gran parte de su misterio una vez que se comprende cómo funcionan.


AND, ORA, EOR y BIT se usan para comparar valores. Pero trabajan de manera diferente a los operadores de comparación CMP, CPX y CPY. Las instrucciones CMP, CPX y CPY dan resultados muy generales. Todo lo que podemos determinar es si dos valores son iguales o no, y si son distintos, que uno es más grande que el otro. Las instrucciones AND, ORA, EOR y BIT son mucho más específicas. Están acostumbradas a comparar bits individuales de un número, y por lo tanto tienen todo tipo de usos.


Lógica Booleanas


Los cuatro operadores lógicos del lenguaje ensamblador usan los principios de una ciencia matemática llamada Lógica Booleanas. En la lógica booleanas, los números binarios 0 y 1 no se utilizan para expresar valores, sino para indicar si una expresión es verdadera o falsa. Si una expresión es verdadera, se dice que su valor en la lógica booleana es 1. Si es falsa, se dice que su valor es 0. En el lenguaje ensamblador del 6502, el operador AND tiene el mismo significado que la palabra «AND» tiene en inglés. Si un bit y otro tienen el mismo valor 1 (son «verdaderos»), entonces el operador también dará un valor 1. Pero si cualquier otra condición existe, si un bit es verdadero y el otra es falso, o si los dos bits son falsos, entonces el operador AND devuelve un resultado 0 (o falso).


Los resultados de los operadores lógicos a menudo se ilustran por medio de las denominadas «tablas de verdad». He aquí la tabla de verdad para el operador AND.


Tablas de verdad para AND


En el lenguaje ensamblador del 6502, la instrucción AND se utiliza a menudo en una operación llamada «bit masking – máscara de bits». El propósito de la máscara de bits es activar o desactivar bits específicos de un número. El operador AND se puede utilizar, por ejemplo, para desactivar cualquier número de bits poniendo un cero en cada bit que se desea borrar. Así es como funciona la máscara de bits:


      100  LDA #$AA; BINARY 1010 1010
      110  AND #$F0; BINARY 1111 0000	

Si su computador encuentra esta rutina en un programa, la siguiente operación AND se llevaría a cabo:


    1010 1010 (contenido del acumulador)
AND 1111 0000
-------------
    1010 0000 (nuevo valor del acumulador)	

Como puede ver, esta operación desactiva el nybble bajo de $AA, dejándolo en $0 (dando un resultado de $A0). La misma técnica funciona con cualquier otro número 8 bits. No importa qué número pase a través de la máscara 1111 0000, su nybble menor siempre saldrá sin cambios de la operación AND.


Descompresión de datos usando el operador «AND»


El operador AND, junto con la instrucción de desplazamiento de bits LSR, puede ser utilizada para descomprimir los datos que han sido comprimidos con la instrucción ASL. He aquí una rutina de ejemplo para descomprimir datos.


      10 ; 
      20 ; UNPACKING DATA
      30 ;
      40 PKDBYT=$C0
      50 LONYB=$C1
      60 HINYB=$C2
      70 ;
      80  *=$0600
      90 ;
      0100  LDA #$45; OR ANYTHING ELSE
      0110  STA PKDBYT
      0120  LDA #0; CLEAR LONYB AND HINYB
      0130  STA LONYB
      0140  STA HINYB
      0150 ;
      0160  LDA PKDBYT
      0165  PHA; SAVE IT ON THE STACK
      0170  AND #$0F; BINARY 0000 1111
      0180  STA LONYB; LOW NYBBLE
      0190  PLA; PULL PKDBYT OFF THE STACK
      0200  LSR A
      0210  LSR A
      0220  LSR A
      0230  LSR A
      0240  STA HINYB; HIGH NYBBLE
      0250  RTS	

El Operador «ORA»


Cuando se utiliza la instrucción ORA ( «o») para comparar un par de bits, el resultado de la comparación es 1 (verdadero) si el valor de cualquiera de los dos bits es 1. Esta es la tabla de verdad de ORA:


Tablas de verdad para ORA


ORA también se utiliza en las operaciones de máscara de bits. He aquí un ejemplo de una rutina de máscara de bits utilizando ORA:


      LDA #VALUE
      ORA $0F
      STA DEST	

Supongamos que el número en VALUE es $22 (binario 0010 0010). La siguiente es la operación de máscara de bits que tendría lugar a continuación.


    0010 0010 (en el acumulador)
ORA 0000 1111
-------------
    0010 1111 (nuevo valor en el acumulador)	

El Operador «EOR»


La instrucción EOR («o exclusivo», o disyunción exclusiva) devolverá un valor verdadero (1) si, y sólo si, uno de los dos bits es un 1. La siguiente es la tabla de verdad del operador EOR.


Tablas de verdad para EOR


La instrucción EOR se utiliza a menudo para comparar bytes y determinar si éstos son idénticos, ya que si cualquier bit de dos bytes es diferente, el resultado de la comparación será distinto de cero. He aquí una ilustración de esa comparación.


    Ejemplo 1             Ejemplo 2
    1011 0110             1011 0110
EOR 1011 0110  Pero : EOR 1011 0111
    ---------             ---------
    0000 0000             0000 0001	

En el ejemplo 1, los bytes que se comparan son idénticos, por lo que el resultado de la comparación es cero. En el Ejemplo 2, un bit es diferente, por lo que el resultado de la comparación es distinto de cero. El operador EOR también se utiliza para obtener el complemento de un valor. Si se hace un EOR entre un valor de 8 bits y $FF, cada bit del valor que es un 1 será reemplazado por un 0, y cada bit que es un 0 será reemplazado por un 1.


    1110 0101 (en el acumulador)
EOR 1111 1111 
    ---------
    0001 1010 (nuevo valor en el acumulador)	

Otra característica útil de la instrucción EOR es que cuando se ejecuta dos veces sobre un número con el mismo operando, el primer número será cambiado a otro número, y luego será de vuelto a su valor original. Esto se muestra en el ejemplo siguiente.


    1110 0101 (en el acumulador)
EOR 0101 0011 
    ---------
    1011 0110 (nuevo valor en el acumulador)
EOR 0101 0011 (el mismo operando de arriba)
    --------- 
    1110 0101 se reestablece el valor original en el acumulador)	

Esta capacidad de la instrucción EOR se utiliza a menudo en gráficos de alta resolución para poner una imagen sobre otra, sin destruir la de abajo. (¡Sí, así es como se hace!)


El operador «BIT»


Esto nos lleva al operador BIT, una instrucción más esotérica que AND, ORA, o EOR. La instrucción BIT se usa para determinar el estado de un bit – o bits – específico de un valor binario almacenado en la memoria. Cuando la instrucción BIT es utilizada en un programa, los bits 6 y 7 del valor examinado se transfieren directamente a los bits 6 y 7 del registro de estado del procesador (los bits de signo y de desbordamiento). Y entonces, se realiza una operación AND sobre el acumulador y el valor en la memoria. El resultado de esta operación AND se almacena en la bandera Z (cero) del registro P. Si hay un 1 tanto en el acumulador como en el valor en la memoria, en la misma posición del bit, el resultado no será cero y la bandera Z se desactivará. Si los bits son diferentes o los dos son igual a cero, el resultado será cero y la bandera Z se activará. El aspecto más importante aquí es que después de que todo esto tiene lugar, los valores en el acumulador y la posición de memoria permanecen sin cambios.