# Programmation Assembleur/x86/Optimisation des performances

* Programmation Assembleur/x86
* Introduction
* Registres
* Les flags
* Copie entre registres et mémoire
* Les branchements
* La pile
* Les interruptions
* Opérations arithmétiques et logiques
* Interactions avec les périphériques
* Optimisation des performances
* Index
* Conclusion
* Modifier ce modèle
Ce chapitre aborde un sujet avancé concernant l'optimisation des performances, notamment en vue de réduire le temps d'exécution des programmes par le processeur. Le sujet s'appuie notamment sur le fonctionnement des processeurs x86, le nombre de cycles, ... Il s'applique également à d'autres processeurs.

## Optimisation par alignement des données en mémoire

Une règle générale d'optimisation concerne l'alignement des données en mémoire :
    Une donnée de n bits (une puissance de 2 : 16, 32, 64) doit être placée à une adresse multiple de n bits en mémoire.
Pour expliquer en détails et mieux comprendre le pourquoi de cette règle, prenons le cas le plus simple du processeur 8086 traitant des données de 16 bits.
Les instructions sont exécutées en plusieurs cycles groupés en phases : T1, T2, T3, Tw et T4. Afin de réduire le nombre de broches du composant, le 8086 multiplexe les adresses (20 bits) et les données (16 bits) dans le temps :
* Les broches AD0 à AD15 présentent l'adresse durant la phase T1, et jouent le rôle de A0 à A15 (Address) ;
* Durant les autres phases (T2 à T4), elles jouent le rôle de D0 à D15 (Data) en lecture ou écriture selon l'opération exécutée ;
* Les broches A16 à A19 présentent les 4 bits de poids forts de l'adresse durant la phase T1.
Dans une architecture 8086, les blocs de mémoire sont séparés deux groupes :
* un pour les octets aux adresses paires, relié aux broches D0 à D7,
* et un autre pour les adresses impaires, relié aux broches D8 à D15.
Les blocs de mémoire permettent d'accéder aux données par mots de 16 bits dont l'adresse est spécifié sur 19 bits (A1 à A19) :
* D15-D8 présente toujours l'octet de l'adresse impaire (A19..A1 1),
* D7-D0 présente toujours l'octet de l'adresse paire (A19..A1 0).
Cependant le 8086 peut lire et écrire des mots de 8 ou 16 bits, à des adresses paires ou impaires :
* Pour les mots de 16 bits aux adresses paires ou les mots de 8 bits (quel que soit la parité de l'adresse), la lecture ou l'écriture s'effectue en une seule fois.
* Pour les mots de 16 bits aux adresses impaires, la lecture ou l'écriture s'effectue en deux fois : l'octet de poids faible à l'adresse (A19..A1 1) sur les broches D15 à D8, puis l'octet de poids fort à l'adresse (A19'..A1' 0) sur les broches D7 à D0 ; où A19'..A1' représente l'adresse A19..A1 + 1 (soit l'adresse sur 20 bits + 2 pour adresser le premier octet du mot de 16 bits suivant).
Selon l'accès mémoire à effectuer, chacun des 2 groupes de bloc mémoire est activé ou non pour prendre en compte ou ignorer les données, en fonction des signaux du 8086 sur les broches suivantes :
* A0 (bit de poids faible de l'adresse) active (0) ou désactive (1) la prise en compte des données D7-D0 ;
* BHE (Bus High Enable) active (0) ou désactive (1) la prise en compte des données D15-D8.
| Lecture/Écriture | BHE | A0 | D15-D8 | D7-D0 |
| Mot de 16 bits sur adresse paire | 0 | 0 | MSB | LSB |
| Mot de 8 bits sur adresse impaire ou LSB d'un mot de 16 bits sur adresse impaire | 0 | 1 | LSB | |
| Mot de 8 bits sur adresse paire ou MSB d'un mot de 16 bits sur adresse impaire | 1 | 0 | | MSB |
| Aucune | 1 | 1 | | |
Pour le 8086, aligner les données de 16 bits à des adresses multiples de 2 permet donc d'éviter une lecture/écriture en deux fois (LSB puis MSB).
Le principe est généralisable pour des données sur 32 bits, 64 bits ou plus.