Assembleur - Définition

Source: Wikipédia sous licence CC-BY-SA 3.0.
La liste des auteurs de cet article est disponible ici.

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 presque aussi efficace qu'un code assembleur écrit à la main, tout en restant beaucoup plus facile (et moins coûteux) à écrire, à lire et à maintenir.

Cependant,

  1. quelques calculs complexes écrits directement en assembleur, en particulier sur des machines massivement parallèles, seront plus rapides, les compilateurs n'étant pas encore assez évolués pour tirer partie des spécificités de ces architectures.
  2. certaines routines (drivers) sont parfois plus simples à écrire en langage de bas niveau.
  3. 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, voire impossibles à écrire dans un langage de haut niveau. Par exemple, les instructions assembleur qui permettent à Windows de gérer le changement de tâche (LGDT et LLDT) sur microprocesseur i386 et suivants ne peuvent pas être émulées ou générées par un langage évolué. Il faut nécessairement les coder dans un court sous-programme assembleur qui sera appelé à partir d'un programme écrit en langage évolué.

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.

La programmation des systèmes embarqués, souvent à base de microcontrôleurs, est une "niche" traditionnelle pour la programmation en assembleur. En effet ces systèmes sont souvent très limités en ressources (par exemple un microcontrôleur PIC 16F84 est limité à 1024 instructions de 14 bits, et sa mémoire vive contient 136 octets). et requièrent donc une programmation de bas-niveau très optimisée pour en exploiter les possibilités. Toutefois, l'évolution du matériel fait que les composants de ces systèmes deviennent de plus en plus puissants à un coût et à une consommation électrique constants, l'investissement dans une programmation "tout assembleur" beaucoup plus coûteuse en heures de travail devient alors un non-sens en termes d'efforts. Typiquement, la programmation en assembleur est beaucoup plus longue, plus délicate (car le programmeur doit prendre en compte tous les micro-détails du développement dont il s'abstient en langage évolué) et donc plus coûteuse que la programmation en langage de haut niveau. Il ne faut donc la réserver qu'aux situations pour lesquelles on ne peut pas faire autrement.

Exemples simples

Voici quelques exemples simples :

  • en syntaxe AT&T (écrits pour l'assembleur GNU (GAS) pour Linux)
  • utilisant le jeu d'instructions i386
  • à utiliser comme suit:
      $ gcc truc.S -c -o truc.o      $ ld truc.o -o truc      $ ./truc      

Afficher Bonjour

(les commentaires se trouvent après les points-virgule)

(Remarque Sept.2010 : Après une petite période d'incompréhension le code ci-dessous fonctionne sous Ubuntu si : 1/ on enlève l'accent sur définition 2/ on met des # à la place des ; pour les commentaires)

               .global _start       BONJ:   .ascii  "Bonjour\n"      ; Définition en mémoire de la chaîne à afficher. \n correspond au saut de ligne       _start: mov     $4      , %eax   ; Mettre 4 dans le registre eax (appel système '''Write'')               mov     $1      , %ebx   ; Mettre 1 dans le registre ebx (descripteur de fichier ''STDOUT'')               mov     $BONJ   , %ecx   ; Mettre l'adresse mémoire de notre chaîne de caractère dans le registre ecx               mov     $8      , %edx   ; Mettre la taille de la chaîne dans edx               int     $0x80            ; Interruption 0x80, exécutant un appel système sous Linux)                      mov     $1      , %eax   ; Mettre 1 dans eax (appel système ''Exit'')               mov     $0      , %ebx   ; Mettre 0 dans ebx (valeur de retour du programme)               int     $0x80            ; Interruption 0x80, exécutant un appel système sous Linux)      

Lire le clavier (16 caractères max) puis l'afficher

       # define N 16                      .global _start                      .comm   BUFF    , N              _start: mov     $3      , %eax               mov     $0      , %ebx               mov     $BUFF   , %ecx               mov     $N      , %edx               int     $0x80                      mov     %eax    , %edx               mov     $4      , %eax               mov     $1      , %ebx               mov     $BUFF   , %ecx               int     $0x80                      mov     $1      , %eax               mov     $0      , %ebx               int     $0x80      
Page générée en 0.095 seconde(s) - site hébergé chez Contabo
Ce site fait l'objet d'une déclaration à la CNIL sous le numéro de dossier 1037632
A propos - Informations légales
Version anglaise | Version allemande | Version espagnole | Version portugaise