Assembleur (langage)
| Image manquante Langage_progr.png image:Langage_progr.png |
| Cet article fait partie de la série Langages de programmation |
| Langages à objets |
| Ada 95 - C++ - C# Common Lisp Delphi - Eiffel - Java Nice - Oz - Python Simula - Smalltalk Visual Basic |
| Langages impératifs |
| APL - ASP - Assembleur BASIC - C - COBOL Forth - FORTRAN - Logo Pascal - Perl - PHP |
| Langages fonctionnels |
| Erlang - Haskell ML/OCaml - Oz Lisp/Common Lisp Scheme |
| Langages déclaratifs |
| Clips - Oz - Prolog |
| Langages concurrents |
| Ada 95 - Erlang Java - Oz |
| Langages balisés |
| HTML - SGML - XML Dialectes XML S-expressions |
| Voir aussi |
| Conception - Codage Tests - Optimisations |
| Sommaire |
Présentation
Le langage assembleur ou langage d'assemblage, dit aussi assembleur tout court, est le langage de programmation lisible pour un humain le plus proche du langage machine utilisé par le microprocesseur de la machine. Le langage machine est une combinaison de bits, il est rendu lisible en remplaçant les valeurs brutes par des symboles appelés mnémoniques.
Ainsi, alors que l'ordinateur reconnaîtra ce que l'instruction machine
10110000 01100001
signifie, pour le programmeur c'est plus simple de se souvenir de son équivalent en langage assembleur :
mov $0x61, %al
(cela signifie de mettre la valeur hexadécimale 61 (97 en décimal) dans le registre 'AL'.)
Contrairement à un langage de haut niveau, il y a une correspondance 1-1 entre le code assembleur et le langage machine, ainsi il est possible de traduire le code dans les deux sens sans perdre d'information. La transformation du code assembleur en langage machine est accomplie par un programme nommé assembleur, dans l'autre sens par un programme désassembleur. Les opérations s'appellent respectivement assemblage et désassemblage. Dans un programme réel en assembleur, c'est un peu plus complexe que cela (on peut donner des noms aux routines, aux variables), et on n'a plus cette correspondance. Sur les premiers ordinateurs, la tâche d'assemblage était accomplie manuellement par le programmeur.
Chaque architecture d'ordinateurs a son propre langage machine, et donc son propre langage d'assemblage (l'exemple ci-dessus est pour le x86). Ces différents langages diffèrent par le nombre et le type d'opérations qu'ils ont à supporter. Ils peuvent avoir des tailles et des nombres de registres différents, et différentes représentations de type de données en mémoire. Tous les ordinateurs sont capables de faire les mêmes choses, ils peuvent les faire de manière différente.
De plus, plusieurs groupes de mnémoniques ou de syntaxe de langage assembleur peuvent exister pour un seul ensemble d'instructions. Dans ce cas, le plus populaire est habituellement celui de la documentation du fabricant. Notre exemple ci-dessus est donné en syntaxe AT&T. En syntaxe Intel, cela donnerait :
MOV AL,61h
C'est vraiment histoire de goût - les opérandes sont inversés - et des possibilités du programme d'assemblage (certains gèrent les deux syntaxes, d'autres une seule). Néanmoins cela ne facilite pas la maintenance des programmes !
Remarquons quand même que cette instruction se traduisant, dans la plupart des langages évolués, par (ici en pseudo-C) :
Al = 0x61 ;
La syntaxe "Intel" semble la plus logique.
Remarquons aussi que en français on dirait :
mettre 0x61 dans AL
La syntaxe "AT&T" semble la plus logique.
Instructions machine
Des opérations de base sont disponibles dans la plupart des jeux d'instructions
- déplacement
- chargement d'une valeur dans un registre
- déplacement d'une valeur depuis un emplacement mémoire dans un registre, et inversement
- calcul
- addition, soustraction, multiplication ou division des valeurs de deux registres et chargement du résultat dans un registre
- combinaison de valeurs de deux registres avec un et/ou logique
- rendre négative la valeur d'un registre arithmétiquement (complément à 2) ou par un non logique (complément à 1)
- modification du déroulement du programme
- saut à un autre emplacement dans le programme (normalement, les instructions sont exécutées séquentiellement, les unes après les autres)
- saut à un autre emplacement, mais après avoir sauvegardé l'instruction suivante afin de pouvoir y revenir (point de retour)
- retour au dernier point de retour
- comparaison
- comparer les valeurs de deux registres
Et on trouve des instructions spécifiques avec une ou quelques instructions pour des opérations qui auraient dû en prendre beaucoup. Exemples :
- déplacement de grands blocs de mémoire
- arithmétique lourde (sinus, cosinus, racine carrée, etc.)
- application d'une opération simple (par exemple, une addition) à un ensemble de données
Directives du langage assembleur
En plus de coder les instructions machine, les langages assembleur ont des directives supplémentaires pour assembler des blocs de données et assigner des adresses aux instructions en définissant des étiquettes ou labels.
Ils sont capables de définir des expressions symboliques qui sont évaluées à chaque assemblage, rendant le code encore plus facile à lire et à comprendre.
Ils ont habituellement un langage macro intégré pour faciliter la génération de codes ou de blocs de données complexes.
Usage du langage Assembleur
Il y a des débats sur l'utilité du langage assembleur. Dans beaucoup de cas, des compilateurs-optimiseurs peuvent transformer du langage de haut niveau dans un code qui tourne de façon plus efficace qu'un code assembleur écrit à la main, tout en restant beaucoup plus facile à lire et à "maintenir".
Cependant,
- quelques calculs complexes écrits directement en assembleur, en particulier sur des machines massivement parallèles, seront plus rapides,
- certaines routines (drivers) sont parfois plus simples à écrire en langage de bas niveau.
- des tâches très dépendantes du système, exécutées dans l'espace mémoire du système d'exploitation sont parfois difficiles à écrire dans un langage de haut niveau.
Certains compilateurs transforment, lorsque leur option d'optimisation la plus haute n'est pas activée, des programmes écrits en langage de haut niveau en code assembleur, chaque instruction de haut niveau se traduisant en une série d'instructions assembleur rigoureusement équivalentes et utilisant les mêmes symboles; cela permet de voir le code dans une optique de débogage et de profilage, ce qui permet de gagner parfois beaucoup plus de temps en remaniant un algorithme. En aucun cas ces techniques ne peuvent être conservées pour l'optimisation finale.
Beaucoup de systèmes embarqués sont aussi programmés en assembleur pour bénéficier du maximum des possibilités de ces systèmes, souvent limités en ressources, bien que progressivement les composants de ces systèmes soient de plus en plus puissants pour un coût identique.
Macro-assembleur
Beaucoup d'assembleurs gèrent un langage de macros. Il s'agit de regrouper plusieurs instructions afin d'avoir un enchaînement plus logique et moins fastidieux.
Par exemple (en assembleur Microsoft MASM) :
putchar Macro car ; Prototype de la macro
ifdef car ; si car est défini
mov dl,car ; le mettre dans dl
endif
mov ah,2 ; ah=2 : fonction "putchar" en DOS
int 21h ; appel au DOS
endm ; fin macro
est une macro qui affiche un caractère sous MS-DOS. On l'utilisera par exemple ainsi :
putchar "X"
Et cela générera :
mov dl,"X"
mov ah,2
int 21h
Cf aussi Programme assembleur
