Pourquoi ce code n'a pas été écrit d'une manière beaucoup plus simple?

8

J'ai rencontré une question en travaillant sur le langage d'assemblage. Voici la question:

Supposons que le bit P2.2 est utilisé pour contrôler une lumière extérieure et le bit P2.5 une lumière à l'intérieur d'un bâtiment. Montrez comment allumer la lumière extérieure et éteindre celle intérieure.

Solution proposée:

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

J'avais juste l'impression que cela ferait exactement le même travail pour coder:

SETB P2.2
CLR P2.5

Qu'est-ce qui ne va pas avec ça?

İlker Demirel
la source
2
Peut-être juste de la didactique - montrant comment utiliser la mèche de transport comme accumulateur. Il n'y a aucun avantage que je puisse voir dans ce cas particulier. Cela ressemble au code d'assemblage 8051.
Spehro Pefhany
@SpehroPefhany Mais pour autant que je sache, le registre Acc est utilisé dans certains cas car c'est le seul registre qui supporte certaines instructions comme DA, RR, RL etc. Je ne pense pas que ce soit le cas ici. Ai-je tort?
İlker Demirel
Le portage est un peu large. Vous voudrez peut-être l'utiliser comme accumulateur dans certains cas, comme l'évaluation de la logique à relais.
Spehro Pefhany

Réponses:

11

Vous avez raison en ce qu'il semble que le code que vous montrez est idiot. Peut-être que la machine sur laquelle cela fonctionne ne peut pas effectuer d'opérations immédiates pour définir des bits sur les ports d'E / S, et c'est pourquoi quelque chose comme SETB P2.2 n'est pas possible.

Régler toujours le bit CY à 1, puis ORing quoi que ce soit dedans est tout simplement stupide. Il en va de même pour mettre le bit CY à 0, puis y ajouter quelque chose. Il est clair que le bit CY peut être directement copié dans un bit de broche d'E / S, car le code le fait. Au plus, cela devrait être 4 instructions, certainement pas 6.

Olin Lathrop
la source
Je peux donc dire que si un bit est adressable par bit, je suis autorisé à utiliser des instructions de bit sur n'importe quel bit, non?
İlker Demirel
1
@ İlk: Pas nécessairement. Il peut y avoir des restrictions comme les instructions de bits ne fonctionnent que sur certains registres, certaines mémoires "proches" et similaires. Sans connaître le processeur, nous ne pouvons pas dire avec certitude si SETB P2.2 aurait été possible. Cependant, SETB C suivi de MOV P2.2, C, est clairement possible.
Olin Lathrop
1
@OlinLathrop: Le processeur est presque certainement une variante 8051, et le jeu d'instructions pour ceux-ci permettrait d'utiliser les mêmes emplacements SETB bitet CLR bitinstructions que pour MOV bit,C. De plus, tout en utilisant des instructions discrètes pour lire un port d'E / S, mettre à jour la valeur et la réécrire produira une sémantique différente de l'utilisation des instructions de lecture-modification-écriture, les instructions au niveau du bit utilisent toutes la même sémantique de lecture-modification-écriture sur I / O ports.
supercat
9

Le code est presque certainement pour un processeur utilisant le jeu d'instructions 8051. Sur ce processeur, la variation de code que vous donnez aurait le même effet que l'original, sauf qu'elle s'exécuterait plus rapidement. L'exécution de "ORL C, P2.2" lorsque le report est défini n'aura aucun effet observable sauf pour gaspiller un certain nombre de cycles (deux cycles CPU totalisant 24 cycles d'horloge sur un 8051 si je me souviens bien; probablement un nombre différent sur certaines autres variantes) . De même avec l'exécution de "ANL C, P2.5" lorsque le report est clair. Bien qu'il puisse y avoir certains types de processeur où une demande de lecture de certains emplacements d'E / S aurait un effet observable, je ne pense pas qu'un processeur de style 8051 ait jamais eu un tel comportement pour les emplacements d'E / S adressables par bit, beaucoup moins pour les bits de P2.

Peut-être que le but du code était de démontrer les instructions ORL C,bitet ANL C,bit, mais cela semble être un exemple étrange pour les démontrer.

supercat
la source
6

Le code d'assembly donné est probablement généré par le compilateur. Il s'agit de la version non optimisée des instructions C suivantes, où P2_2et P2_5sont les objets adressables par bit:

P2_2 |= 1;
P2_5 &= 0;

Cela peut sembler équivalent à P2_2 = 1;et P2_5 = 0;, mais ce n'est pas le cas si les registres adressables par bit sont des objets volatils. Une opération de lecture-modification-écriture sur un objet volatil doit effectuer la lecture et l'écriture, dans cet ordre. Cela garantit que tous les effets secondaires de la lecture ou de l'écriture du registre se produisent réellement.

Bien que je ne connaisse aucun registre adressable par 8051 bits avec des effets secondaires, un compilateur ne peut pas supposer qu'il n'y en a pas ou ne le sera jamais.

D Krueger
la source
1
Bon point sur la possibilité d'être généré par le compilateur. Cependant, cela déplace ensuite la question de savoir pourquoi quelqu'un écrirait P2_2 | = 1 au lieu de simplement P2_2 = 1.
Olin Lathrop
3

La vraie différence entre ceux-ci peut être subtile.

Dans votre réponse simplifiée, la logique est de lire le port, de définir ou d'effacer la valeur du bit, puis de la réécrire sur le port. Notez que le port entier pourrait être réécrit ici.

La solution, d'autre part, utilise l'instruction de bit MOV qui peut fonctionner d'une manière assez différente.

Sans entrer dans les détails de la pièce particulière utilisée ici, il est difficile de déterminer s'il y a une différence ou si elle est importante.

Ou ce pourrait être juste que l'instructeur a décidé de vous faire réfléchir ... ce qui est après tout ... son vrai travail.

Trevor_G
la source
0

La seule réponse est que le processeur ne prend pas directement en charge les instructions 1 bit. Cependant, lorsque le bit de retenue est utilisé, il sait qu'il ne s'agit que d'un bit en cours de manipulation.

Guill
la source