« Les opérations bit à bit/Les subtilités du XOR » : différence entre les versions

Contenu supprimé Contenu ajouté
mAucun résumé des modifications
Ligne 1 :
Dans cette partie, nous allons voir ce qu'il est possible de faire avec l'instruction XOR. Les techniques suivantes se basent sur les propriétés de l'opération XOR. Pour rappel, nous avons vu au premier chapitre que : <math>a \oplus 0 = a</math> et <math>a \oplus a = 0</math>. Ces deux propriétés sont assez importantes, surtout la dernière. La première méthode a été utilisée dans le chapitre sur les masques, aussi nous ne l'utiliserons pas plus.
Dans cette partie, nous allons voir ce qu'il est possible de faire avec l'instruction XOR.
 
==Inégalité des signes de deux entiers==
Ligne 30 :
</source>
 
==Émulation d'instructions==
==Mise à zéro rapide==
 
L'instruction XOR permet parfois d'émuler certaines opérations plus complexes. Elle permet notamment d'émuler des transferts entre registres/variables ou des initialisations de registres. Son utilisation première est notamment la mise à 0 d'un registre ou d'une variable.
 
===Mise à zéro rapide===
 
Initialiser une variable à 0 est une opération extrêmement courante. En conséquence, il vaut mieux la rendre la plus rapide possible. S'il n'y a pas de méthode particulière pour cela dans les langages de haut-niveau, les compilateurs ont cependant quelques possibilités d'optimisation. Il y a en effet plusieurs méthodes pour mettre un registre à 0 en assembleur, certaines n'étant compatibles qu'avec certaines processeurs. Certaines processeurs ont une instruction machine pour mettre à 0 un registre : c'est alors la solution idéale dans la (quasi-)totalité des cas. Sur les architectures n'ayant pas cette instruction, on peut utiliser une instruction MOV (ou équivalent). On peut l'utiliser en adressage immédiat : on place alors la constante 0 dans le registre. D'autres processeurs possèdent un registre spécial, qui conserve en permanence la valeur 0 et n'est pas accessible en écriture. Il suffit alors d'effectuer un MOV de ce registre vers le registre à initialiser. Mais il existe une dernière solution : faire un XOR entre le registre et lui-même. C'est notamment ce qui est fait sur les architectures x86.
 
Pour comprendre pourquoi cette solution fonctionne, il faut rappeler que l'on obtient 0 lorsque l'on XOR un bit avec lui-même : <math>a \oplus a = 0</math>. Si cela vaut pour un bit, cela s'applique aussi quand on effectue un XOR bit à bit sur un nombre : chacun de ses bits sera donc XORé avec lui-même, ce qui fait qu'un nombre XOR lui-même donnera toujours zéro. Cette propriété est utilisé par les compilateurs pour mettre à zéro un registre. Sur les architectures x86, cette solution est légèrement meilleure que celle utilisant un MOV avec adressage immédiat. Cette dernière solution demande d'intégrer une constante en adressage immédiat, qui prend facilement 8 à 16 bits. Un nom de registre est beaucoup plus court, ce qui fait que que la solution avec un XOR donne des instructions plus petites. Sur d'autres processeurs, qui ne supportent pas l'adressage immédiat, la constante est lue depuis la mémoire. En comparaison, un XOR entre deux registres ne va rien charger en RAM et est donc plus rapide.
 
===Émulation du MOV===
 
L'opération XOR permet d'émuler une instruction MOV sur les processeurs qui n'en disposent pas, comme certains processeurs MIPS. Le MOV est alors remplacé par une opération XOR à trois adresses, qui XOR le registre à copier avec zéro, et place le résultat dans le registre de destination. L'opération est d'autant plus utile que ces processeurs disposent d'un registre en écriture seule, qui contient toujours la valeur 0.
 
Pour résumer : MOV Ra -> Rb <=> Ra XOR 0 -> Rb
 
==Échange de deux variables==