¿Por qué este código no se escribió de una manera mucho más simple?

8

Me encontré con una pregunta mientras trabajaba en lenguaje ensamblador. Aquí está la pregunta:

Suponga que el bit P2.2 se usa para controlar una luz exterior y el bit P2.5 una luz dentro de un edificio. Muestre cómo encender la luz exterior y apagar la luz interior.

Solución dada:

SETB C            ; CY = 1
ORL C, P2.2       ; CY = P2.2 ORed w/ CY
MOV P2.2, C       ; turn it on if not on
CLR C             ; CY = 0
ANL C, P2.5       ; CY = P2.5 ANDed w/P2.5
MOV P2.5,C        ; turn it off if not off

Sentí que haría el mismo trabajo codificar:

SETB P2.2
CLR P2.5

¿Qué está mal con eso?

İlker Demirel
fuente
2
Tal vez solo didáctica: muestra cómo usar el bit de acarreo como acumulador. No hay ninguna ventaja que pueda ver en este caso particular. Esto se parece al código de ensamblaje 8051.
Spehro Pefhany
@SpehroPefhany Pero hasta donde yo sé, el registro Acc se usa en algunos casos ya que es el único registro que admite algunas instrucciones como DA, RR, RL, etc. No creo que este sea el caso aquí. ¿Me equivoco?
İlker Demirel
El transporte es un poco ancho. Es posible que desee utilizarlo como acumulador en algunos casos, como la evaluación de lógica de escalera.
Spehro Pefhany

Respuestas:

11

Tiene razón en que parece que el código que muestra es una tontería. Quizás cualquier máquina en la que se ejecute no pueda realizar operaciones inmediatas para establecer bits en los puertos de E / S, y es por eso que algo como SETB P2.2 no es posible.

Aún estableciendo el bit CY en 1, entonces ORing cualquier cosa en él es simplemente tonto. Lo mismo se aplica para establecer el bit CY en 0, y luego ponerle algo AND. Claramente, el bit CY se puede copiar directamente en un bit pin de E / S, ya que el código lo hace. A lo sumo, esto debería ser 4 instrucciones, ciertamente no 6.

Olin Lathrop
fuente
Entonces, puedo decir que si un bit es direccionable, puedo usar instrucciones de bit en cualquier bit, ¿verdad?
İlker Demirel
1
@ İlk: No necesariamente. Puede haber restricciones, ya que las instrucciones de bits solo funcionan en ciertos registros, cierta memoria "cercana" y similares. Sin conocer el procesador, no podemos decir con certeza si SETB P2.2 hubiera sido posible. Sin embargo, SETB C seguido de MOV P2.2, C, es claramente posible.
Olin Lathrop
1
@OlinLathrop: El procesador es casi seguro una variante 8051, y el conjunto de instrucciones para esos permitiría usar las mismas ubicaciones SETB bite CLR bitinstrucciones para MOV bit,C. Además, al usar instrucciones discretas para leer un puerto de E / S, actualizar el valor y volver a escribirlo producirá una semántica diferente del uso de las instrucciones de lectura-modificación-escritura, todas las instrucciones bit a bit usan la misma semántica de lectura-modificación-escritura en I / O puertos.
supercat
9

El código es casi seguro para un procesador que utiliza el conjunto de instrucciones 8051. En ese procesador, la variación de código que proporcione tendría el mismo efecto que el original, excepto que funcionaría más rápido. Ejecutar "ORL C, P2.2" cuando se establece el transporte no tendrá ningún efecto observable, excepto para desperdiciar cierto número de ciclos (dos ciclos de CPU que suman 24 ciclos de reloj en un 8051 si recuerdo correctamente; probablemente un número diferente en algunas otras variantes) . Del mismo modo con la ejecución de "ANL C, P2.5" cuando el transporte es claro. Aunque puede haber algunos tipos de procesadores en los que una solicitud de lectura de algunas ubicaciones de E / S tendría algún efecto observable, no creo que ningún procesador de estilo 8051 haya tenido ese comportamiento en ninguna ubicación de E / S direccionable por bit, mucho menos para bits de P2.

Quizás el propósito del código era demostrar las instrucciones ORL C,bity ANL C,bit, pero este parece un ejemplo extraño para demostrarlas.

Super gato
fuente
6

El código de ensamblado dado es probablemente generado por el compilador. Es la versión no optimizada de las siguientes instrucciones C, donde P2_2y P2_5son los objetos direccionables en bits:

P2_2 |= 1;
P2_5 &= 0;

Esto puede parecer equivalente a P2_2 = 1;y P2_5 = 0;, pero no lo es si los registros direccionables en bits son objetos volátiles. Una operación de lectura-modificación-escritura en un objeto volátil debe realizar la lectura y la escritura, en ese orden. Esto asegura que ocurran los efectos secundarios de leer o escribir el registro.

Aunque no conozco ningún registro direccionable de bits 8051 con efectos secundarios, un compilador no puede asumir que no existe o que nunca lo habrá.

D Krueger
fuente
1
Buen punto sobre posiblemente ser generado por el compilador. Sin embargo, luego mueve la pregunta de por qué alguien escribiría P2_2 | = 1 en lugar de solo P2_2 = 1.
Olin Lathrop
3

La verdadera diferencia entre estos puede ser sutil.

En su respuesta simplificada, la lógica es leer el puerto, establecer o borrar el valor de bit y luego volver a escribirlo en el puerto. Tenga en cuenta que todo el puerto podría reescribirse aquí.

La solución, por otro lado, utiliza la instrucción de bit MOV que puede operar de una manera bastante diferente.

Sin entrar en los detalles de la parte particular utilizada aquí, es difícil determinar si hay una diferencia o si es importante.

O podría ser que el instructor decidió hacerte pensar ... que es, después de todo ... su verdadero trabajo.

Trevor_G
fuente
0

La única respuesta es que el procesador no admite instrucciones de 1 bit directamente. Sin embargo, cuando se utiliza el bit de acarreo, sabe que solo se está manipulando un bit.

Guill
fuente