lunes, 20 de junio de 2016

¿Par o impar? ¿Cero o no cero? ¿Multiplo de algo? ¿Bit o no bit?

Existen herramientas y técnicas en bajo nivel con las que no se cuenta -o no se conocen popularmente- en alto nivel. Es por ello que para el programador que viene del alto mundo suponga un reto hacer cosas que en el bajo fondo de assembler ... son muy sencillas (tanto como lo puede ser resolver cosas en assembler).
Para comprender lo que sigue a continuación es necesario que tenga un manejo medianamente fluido del sistema binario. Los ejemplos serán de operandos en 8 bits, aunque por supuesto las técnicas aplicarán a palabras de cualquier longitud.
La unidad aritmético-lógica (ALU) cuenta con una palabra de estado donde cada bit corresponde a una bandera o indicador (flag) que se actualiza en función de la última operación. 
A esta palabra de estado se la conoce como CCR (Condition Code Register), Status Word, etc. En el Motorola 68HC11 tiene una longitud de 8 bits, en el gráfico a continuación vemos el significado de cada bit:

¿Cuándo se actualizan los bits de la palabra de estado? La respuesta -citando a una autoridad en la materia- es: depende. ¿De qué depende? De la instrucción. En el set de instrucciones encontramos columnas con los flags de la palabra de estado y una indicación del efecto de la instrucción en ellos. Tomemos como ejemplo la primera de las instrucciones del set: ABA:
En este caso cada flag tiene un guión o un delta (eso que parece un triángulo). El guión significa que la ejecución de la instrucción no cambia el estado del flag, por tanto mantiene el valor que tenia. El delta indica que la ejecución actualizará el flag según el resultado de la operación. Por tanto adoptará el valor 0 o 1 según lo que resulte de la operación. Algunas instrucciones provocan que un determinado flag adopte el valor 0 o 1 sin importar los operandos. Observe por ejemplo la instrucción CLR:
Al ejecutar CLR los valores de N, Z, V y C serán siempre los mismos. Este es un caso particular en el que cuatro flags podríamos decir que se actulizan de forma determinística (sin importar el operando), la gran mayoría de las instrucciones cambian los valores de los flags en función del resultado, por lo que pueden adoptar el valor 0 o 1.
Nos centraremos en dos de los flags: Z (cero) y N (negative). El primero será 1 si la ejecución de la instrucción dio por resultado cero. En el caso de las instrucciones aritméticas es sencillo de comprender: si una suma o resta dan cero, entonces Z=1. Lo mismo ocurre si realizamos una comparación, ya que no se trata de otra cosa que una resta de la que no nos importa el resultado. Pero note que las instrucciones de carga (Load) también actualizan Z, como podemos ver en LDAA:
Por tanto al ejecutar alguna instrucción de carga (LDAA, LDAB, LDD, LDX, LDY) lo que se carga -sea en A, B, D, IX, IY- es cero, el flag Z tomará el valor 1. No es necesario comparar lo cargado con cero para actualizar el flag. 
Entonces, ¿cómo determinar si un byte o palabra es cero? Basta con cargarlo en un acumulador y emplear el flag Zero para saberlo. Si estuviéramos recorriendo un vector y contando los ceros en "ceros" podríamos por ejemplo hacer algo así:

        LDX dirIni
        LDAA 0,x
        BNE noCero
        INC ceros
noCero  ...


Si la consigna fuera contar los que no son cero, alcanza con cambiar BNE por BEQ en esta porción de programa de ejemplo.

En la próxima veremos como seguir contestando las preguntas trascendentales que hemos planteado.

3 comentarios:

  1. Profe, una consulta sobre Assembler para Polling:
    En un ejercicio dice: "Escribir una rutina que permita almacenar en el acumulador A el valor del numero presionado en el teclado" (es decir el valor que esta en el Registro de Datos, porque el ejercicio es casi igual al de la guia que hicimos hoy).
    En ese caso, como no dice armar un vector, hay que cargar el valor en A y continuar el bucle infinito, mas alla de que despues el valor se vaya pisando continuamente?
    Muchas Gracias

    ResponderBorrar
  2. Hola! Si no pide mas nada que eso, correcto, solo se cargaría en el acumulador A

    ResponderBorrar

Aunque no es obligatorio, es de buena educación firmar los comentarios.