AccueilđŸ‡«đŸ‡·Chercher

Code Ă  trois adresses

En informatique, le code Ă  trois adresses[1] (TAC ou 3AC) est un type de langage intermĂ©diaire utilisĂ© par les compilateurs comme Clang/LLVM. Chaque instruction TAC a au plus trois opĂ©randes et est gĂ©nĂ©ralement une combinaison d'affectation et d'un opĂ©rateur binaire. Par exemple : t1 := t2 + t3. Le nom dĂ©rive de l'utilisation de trois opĂ©randes dans ces instructions mĂȘme si des instructions avec moins d'opĂ©randes peuvent se produire.

Étant donnĂ© que le code Ă  trois adresses est utilisĂ© comme langage intermĂ©diaire dans les compilateurs, les opĂ©randes ne seront probablement pas des adresses mĂ©moire concrĂštes ou des registres de processeur, mais plutĂŽt des adresses symboliques qui seront traduites en adresses rĂ©elles lors de l'allocation des registres. Il n'est pas rare non plus que les noms d'opĂ©randes soient numĂ©rotĂ©s sĂ©quentiellement, car le code Ă  trois adresses est gĂ©nĂ©ralement gĂ©nĂ©rĂ© par le compilateur.

Exemples

Calcul d'une solution d'une équation du second degré

En code à trois adresses, cela se décompose en plusieurs instructions distinctes, plus faciles à traduire en langage d'assemblage. Il est également plus facile de détecter des sous-expressions qui se répÚtent, pour raccourcir le code.

Instruction Ă  convertir :

Écriture dans un langage de programmation classique :

x = (-b + sqrt(b^2 - 4*a*c)) / (2*a)

Code Ă  trois adresses :

t1 := b * b
t2 := 4 * a
t3 := t2 * c
t4 := t1 - t3
t5 := sqrt(t4)
t6 := 0 - b
t7 := t5 + t6
t8 := 2 * a
t9 := t7 / t8
x := t9

Boucle

Le code Ă  trois adresses peut avoir des sauts conditionnels et inconditionnels et des mĂ©thodes d'accĂšs Ă  la mĂ©moire. Il peut Ă©galement avoir des mĂ©thodes d'appel de fonctions. De cette façon, le code Ă  trois adresses peut ĂȘtre utile dans l'analyse de flux de contrĂŽle. Dans l'exemple de type C ci-aprĂšs, une boucle stocke les carrĂ©s des nombres entre 0 et 9 :

int b[10];
for (int i = 0; i < 10; ++i) {
    b[i] = i * i; 
}
     t1 := 0               ; Initialisation de i
     t2 := b               ; Initialisation d'un pointeur sur b[i]
L1:  if t1 >= 10 goto L2   ; Saut conditionnel
     t3 := t1 * t1         ; Calcul du carré de i
     *t2 := t3             ; Déréférencement, affectation dans b[i]
     t1 := t1 + 1          ; Incrémentation de i
     t2 := t2 + 4          ; Passage Ă  la case b[i] suivante
     goto L1               ; Répétition de la boucle
L2:

Le code Ă  trois adresses sur la droite contient une optimisation : le pointeur t2, qui parcourt les cases du tableau b, est incrĂ©mentĂ© en synchronisation avec i. Le chiffre 4 correspond au nombre d'octets utilisĂ© par chaque case de b (en C, une variable de type int occupe gĂ©nĂ©ralement 4 octets). Sans cette optimisation, il aurait Ă©tĂ© nĂ©cessaire d’utiliser deux adresses (appelĂ©es t4 et t5 ci-dessous) Ă  la place de la simple adresse t2 :

t4 := i * 4
t5 := b + t4
*t5 := t3

Voir aussi

Notes et références

  1. Aho, Alfred V. (Sethi, Ravi., Ullman, Jeffrey D., 1942-), Compilers, principles, techniques, and tools, Reading, Mass., Addison-Wesley Pub. Co, , 466 (ISBN 0201100886, OCLC 12285707, lire en ligne Inscription nécessaire)


Cet article est issu de wikipedia. Text licence: CC BY-SA 4.0, Des conditions supplĂ©mentaires peuvent s’appliquer aux fichiers multimĂ©dias.