Aller au contenu

Instruction informatique

Un article de Wikipédia, l'encyclopédie libre.

Une instruction informatique est une étape dans un programme informatique[1]. Une instruction ordonne à l'ordinateur l'acte qu'il doit poser avant de passer à l'instruction suivante. Un programme informatique est constitué d'une suite d'instructions.

Contexte théorique

[modifier | modifier le code]
Schématisation de l'architecture de von Neumann

Contrairement à un calculateur, dont le rôle se limite à réaliser des opérations de calcul (le plus souvent arithmétiques), un ordinateur assure des opérations de traitement de l'information, c'est-à-dire qu'il exécute successivement des opérations en suivant les directives d'un algorithme. Ce traitement est mené à l'aide d'instructions plus ou moins sophistiquées, et plus ou moins proches du microprocesseur. Par instruction informatique on entend donc décrire une commande unique, représentée par un symbole (numérique ou alpha-numérique, dit mnémoniques), et dont la finalité est prédéfinie : de la plus simple (déplacer l'index du microprocesseur dans la mémoire, additionner deux nombres) à la plus sophistiquée et abstraite (par exemple les instructions de gestion de classes du langage Java)[2].

Historiquement, cette particularité de l'ordinateur qui conduit des traitements en exécutant successivement des instructions est directement reliée au principe de la machine de Turing créé par Alan Turing pour donner une définition précise au concept d'algorithme[3]. Cette machine est un modèle abstrait d'un appareil mécanique de calcul auquel on aurait rajouté un ruban (de la mémoire) et une tête de lecture (le processeur) susceptible de mener des traitements d'après des symboles interprétés par la table des actions (les instructions). Le concept de machine de Turing original était censé représenter une mécanique imaginaire exécutant une procédure. C'est John von Neumann qui s'est chargé de transformer le travail théorique de Turing en une machine fonctionnelle en définissant une architecture dite de von Neuman.

Les instructions dans l'architecture de von Neumann

[modifier | modifier le code]

Telle que définie, la machine de Turing ne décrit pas précisément ce que pourrait être une instruction ni un algorithme. Elle se limite à une définition abstraite. Une « table d'actions » indique à la « tête de lecture/écriture » de la machine, en fonction de son état courant, quel symbole écrire, et comment se déplacer lors de la prochaine action. Le nouvel état est défini en fonction du symbole lu sur le ruban et de l'état courant de la machine.

Dans un programme s'exécutant sur un ordinateur, on pourrait considérer que la tête de lecture correspond à l'action de lecture par le processeur d'un symbole contenu dans la mémoire, que ce symbole correspond à une action précise (additionner, avancer, etc), qui conduira une fois accomplie à la lecture du symbole suivant et ainsi de suite.

Ce concept de symbole sur un ruban correspond très précisément à l'idée d'instruction informatique contenue dans une mémoire. Et la « table d'actions » de la machine de turing peut être considérée comme correspondant au cœur du microprocesseur et à l'ensemble des actions (on peut parler de jeu d'instruction ou de langage) qu'il est en mesure de réaliser pour chaque instruction donnée.

Type d'instructions

[modifier | modifier le code]

Une instruction informatique est incluse dans un jeu d'instructions qui composent le langage de programmation. La forme et la puissance de ce jeu d'instructions est influencée par l'architecture qui va la faire fonctionner. Elle est également contrainte par son degré d'abstraction par rapport au micro-processeur. Les instructions informatiques sont en effet plus ou moins proches de ce dernier : du langage machine, directement compris par le micro-processeur, aux langages évolués, eux-mêmes composés d'instructions interprétées ou transformées dans un langage de plus bas niveau tel que le langage machine, puis transmises au micro-processeur via des dispositifs matériels et logiciels intermédiaires plus ou moins nombreux[4].

Instructions en langage machine

[modifier | modifier le code]

Le langage machine est la suite de bits qui est interprétée par le processeur d'un ordinateur exécutant un programme informatique. Ce langage directement compris par un processeur est composé d'instructions à traiter codées sous une forme binaire. Pour leur intelligibilité ces instructions sont symboliquement représentées par un vocabulaire compréhensible par les humains intitulé assembleur ou langage assembleur[5].

Par exemple, un micro-processeur de la famille x86 d'Intel reconnaît une instruction stockée dans une de ses mémoires sous la forme binaire :

 10110000 01100001

Et en langage assembleur, cette instruction est représentée par un équivalent intelligible pour le programmeur :

  movb $0x61,%al

Le langage machine est le groupe d'instructions élémentaires qui permet de donner des ordres au microprocesseur. Tout logiciel (y compris les langages de programmation évolués) qui fonctionne sur un ordinateur voit en dernier recours ses ordres exécutés par le micro-processeur via des instructions de la famille du langage machine, et stockées sous une forme binaire.

Instructions du langage évolué

[modifier | modifier le code]

Il existe de nombreux niveaux d'abstractions qui permettent de mettre en œuvre des instructions plus ou moins éloignées de celles directement compréhensibles par le micro-processeur, les instructions en langage machine. Les langages dits évolués, c'est-à-dire qui proposent des instructions qui doivent faire l'objet d'étape intermédiaire d'interprétation avant d'être comprises et exécutées par le processeur, peuvent pratiquement proposer n'importe quelle instruction, d'un niveau de complexité sans limite.

Ces instructions de langages évoluées peuvent être très spécialisées : le langage R par exemple, dédié aux programmations de modèles statistiques, propose des instructions qui vont de la statistique multivariée aux méthodes de ré-échantillonnage, de l'économétrie à la biométrie, des modèles de régression sur séries chronologiques ou les modèles à équations simultanées.

Des langages de programmation sophistiqués tels que Java ou C possèdent des instructions classiques dédiées au traitement de données, à la gestion des conditions et aux calculs arithmétiques, mais aussi des instructions particulièrement complexes capables de manipuler une base de données, ou un écran graphique.

Familles d'instructions

[modifier | modifier le code]

Les instructions sont chargées de réaliser des traitements plus ou moins complexes. S'inscrivant dans le cadre théoriques des machines de Turing et de l'architecture de von Neumann, l'action des instructions est en premier lieu conditionnée par des besoins en relation avec l'algorithmique et l'architecture de l'ordinateur.

La plus simple des instructions est l'instruction nulle qui, comme son nom l'indique, ne commande l'exécution d'aucun traitement et n'existe que pour des raisons pratiques particulières.

Les familles d'instruction s'inscrivant dans le cadre algorithmique de la machine de Turing comprennent notamment des commandes de gestion des conditions (réaliser une action si une condition est remplie), de traitement (appliquer une transformation à une information - par exemple une valeur contenue en mémoire) ou encore de répétition et de branchement (passer d'un endroit à un autre du programme ou répéter plusieurs fois une même portion de programme).

Les instructions de nature algorithmique se retrouvent dans tous les microprocesseurs. Dans les plus évolués elles peuvent être très sophistiquées et traiter des opérations arithmétiques complexes, des calculs en virgule flottante avec un degré variable de précision, le cas échéant simultanément.

Les langages informatiques de haut niveau et spécialisés peuvent également offrir des instructions sophistiquées réalisant par exemple l'intégralité du calcul d'une fonction ou l'affichage d'une image en trois dimensions.

Les familles instructions concernées par l'aspect fonctionnel lié à la structure de l'ordinateur doivent assurer la gestion des échanges entre mémoires et entre registres, ainsi que la communication avec l'extérieur du micro-processeur, et notamment vers les dispositifs d'entrée-sortie (qui permettent d'écrire et de lire des données sur un disque dur ou une mémoire USB par exemple). Dans les ordinateurs les plus évolués les instructions liées au fonctionnement peuvent prendre en charge des opérations sophistiquées telles que la manipulation de mémoire à haute vitesse (comme dans les processeurs de cartes graphiques) ou tout ou partie de la gestion d'un échange de données (réseau, ports de communication).

Traitement et représentation des instructions

[modifier | modifier le code]

Les anciennes cartes perforées (équivalentes des mémoires) contenaient les instructions informatiques sous une forme proche du binaire du langage machine. ce mode de stockage était également en vigueur pour les premiers langages évolués (tels que le Fortran ou le Cobol). De manière générale, une instruction est toujours stockée sous une forme codée. Néanmoins, sur les systèmes informatiques modernes, par souci d'intelligibilité et de compréhension, les instructions sont toujours présentées à l'utilisateur sous une forme symbolique alphanumérique et mnémonique.

Il n'en demeure pas moins que le micro-processeur ne comprend que les instructions du langage machine, ce qui signifie qu'avant d’être transmise au microprocesseur en vue de son exécution, l'instruction doit subir un processus de transformation de sa forme symbolique intelligible vers une forme codée binaire.

Implémentation du jeu d'instructions dans un processeur

[modifier | modifier le code]

Au niveau matériel de l'ordinateur, le jeu d'instructions composé des instructions machines constitue l'ensemble des opérations élémentaires qu'un programme peut demander à un processeur de traiter. C'est l'ordre le plus simple que peut comprendre et exécuter un processeur d'ordinateur en utilisant l'ensemble des circuits logiques qui sont physiquement implémentées dans le processeur. Ces circuits permettent d'effectuer des opérations élémentaires (addition, ET logique) ou plus complexes (division, passage en mode basse consommation)[6].

Architecture CISC

[modifier | modifier le code]

Un microprocesseur à jeu d'instruction étendu (en anglais : Complex Instruction Set Computer) désigne un microprocesseur qui implémente un jeu d'instructions comprenant de très nombreuses instructions mixées à des modes d'adressages complexes. L'architecture CISC est opposée à l'architecture RISC (Reduced Instruction-Set Computer). La plupart des micro-processeurs prévus pour les serveurs ou les stations de bureau implémentent un jeu d'instructions CISC[7].

Architecture RISC

[modifier | modifier le code]

Le microprocesseur à jeu d'instruction réduit (en anglais : Reduced Instruction Set Computer[8] : RISC en anglais) est un type d'architecture matérielle de microprocesseurs, qui se caractérise par un jeu d'instructions réduit, facile à décoder et comportant uniquement des instructions simples. Le code informatique écrit avec des instructions RISC est généralement moins compact, puisque toutes les instructions sont de même taille, alors que les instructions les plus utilisées sont plus courtes dans un jeu d'instruction CISC. Les appareils portables modernes (tels que les IPad ou les Smartphones) utilisent très souvent des processeurs RISC de type ARM[9].

Cycles d'exécution

[modifier | modifier le code]
Diagramme fonctionnel d'un processeur simple exécutant une instruction

Une instruction est exécutée par le processeur au cours d'un cycle (également appelé cycle de recherche et exécution ou encore fetch-decode-execute cycle, FDX). Les quatre étapes successives que les architectures von Neumann utilisent sont la recherche de l'instruction, le décodage de l'instruction (opération et opérandes), l'exécution de l'opération et pour finir l'écriture du résultat. Cette séquence constitue le cycle d'une instruction et est répété continuellement par le micro-processeur, tant qu'il est en fonctionnement. Au démarrage le premier cycle active la lecture de l'instruction contenue dans la case mémoire 0 et ainsi de suite[10].

Ces cycles d'exécutions de base pour une instruction, qui servent de référence pour le calcul des performances d'un micro-processeur, sont exprimés parfois en Instructions par seconde (la plupart du temps exprimée en million d'instructions par seconde, MIPS). La notion cycle d’exécution ne concerne que les instructions en langage machine.

Les instructions plus complexes d'un langage de programmation (comme une boucle for en C ou Java) sont elles-mêmes décomposées en milliers d'instructions en langage machine pour être exécutées sur un microprocesseur, le plus souvent lors de l'étape de compilation.

Interprétation et compilation des instructions de langages évolués

[modifier | modifier le code]

Les instructions d'un programme doivent toujours, in fine, être converties sous une forme directement lisible par le processeur. C'est le compilateur qui est chargé de transformer les instructions d'un code source écrit dans un langage de programmation en code machine[11]. Cette opération peut parfois exiger plusieurs étapes intermédiaires, comme dans le cas du langage Java, par exemple, qui voit ses instructions d'abord transformées par une première étape de compilation, en vue d'être lisible par une machine virtuelle qui elle-même réalisera une nouvelle interprétation en instructions machines pour exécuter le programme. C'est le principe du langage dit semi-interprété.

Avec d'autres langages tels que C, la transformation appliquée aux instructions vise à créer un programme exécutable, c'est-à-dire dont les instructions sont directement lisibles par le micro-processeur. On parle alors de langage compilé[12].

Pour finir, le cas du langage assembleur est particulier puisque, en ce qui le concerne, le fichier source d'un programme contient des représentations textuelles (mnémoniques) des instructions du micro-processeur. Il est donc impératif de transformer la forme textuelle des instructions du programme en une forme binaire compréhensible par le processeur. On parle par usage de compilateur pour le langage assembleur mais, à proprement parler, un compilateur assembleur procède plutôt à une simple conversion de format[5].

Instruction-machine

[modifier | modifier le code]

Taille des instructions

[modifier | modifier le code]

La taille d'une instruction dépend de l'architecture de la plateforme, mais elle est usuellement comprise entre 4 et 64 bits. Voici un exemple d'instruction x86 dans la notation symbolique d'un langage assembleur :

SHL   AX, 01

On appelle SHL un opérateur, et AX, 01 des opérandes. AX est le nom d'un registre de processeur, 01 est une constante. Dans cet exemple, SHL est une abréviation mnémonique pour « shift left » (décalage vers la gauche). L'instruction provoque le décalage vers la gauche d'un bit de la valeur enregistrée dans le registre AX.

Instructions les plus fréquentes

[modifier | modifier le code]

On peut classer les instructions qu'un microcontrôleur est capable d'effectuer en quelques groupes.

Instructions de transfert

[modifier | modifier le code]

Un processeur passe une grande partie de son temps à transférer des octets d'un endroit à l'autre du système : d'un périphérique informatique vers un registre du processeur ou vice-versa, d'un registre vers la mémoire vive ou vice-versa. Parfois, on ne peut pas effectuer de transfert direct d'un composant à l'autre : il faut dans ce cas faire transiter les informations par l'un des registres internes. Remarquons que, sauf exception, il s'agit plutôt d'une copie que d'un transfert puisque la case mémoire d'origine garde son information (tant qu'on n'a pas écrit autre chose à la place).

Instructions arithmétiques

[modifier | modifier le code]

Les processeurs les plus simples ne permettent que d'effectuer des additions et des soustractions, voire des multiplications et des divisions sur des nombres entiers de la taille d'un mot. C'est notamment le cas des microcontrôleurs. Cependant, les processeurs modernes disposent généralement d'une unité de calcul en virgule flottante capable d'effectuer des calculs sur les nombres à virgule. En l'absence d'une telle unité, les nombres à virgule doivent être traités en logiciel.

De même, certains anciens processeurs étaient capables d'effectuer des opérations mathématiques complexes telles que le traitement des grands nombres, des nombres fractionnaires, des puissances, des racines carrées, des fonctions trigonométriques, logarithmiques et exponentielles. Sur les processeurs modernes, ces opérations sont généralement réalisées en logiciel à l'aide des opérations mathématiques de base.

Instructions logiques

[modifier | modifier le code]

Les processeurs sont capables d'effectuer des opérations logiques : ET, OU, XOU (XOR), NON (inverseur), rotations, décalages. Les opérations sont opérées simultanément sur les bits correspondants des deux registres.

La comparaison des octets A et B, qui est considérée comme une opération logique, est réalisée comme une soustraction dont on néglige le résultat ; on s'intéresse simplement au fait de savoir s'il est nul (ce qui signifie que A = B), positif (A > B) ou négatif (A < B). Ces indications sont inscrites dans des indicateurs d'états (petites mémoires d'un bit situées dans le processeur).

Instructions d'entrées/sorties

[modifier | modifier le code]

Ces instructions permettent de s'interfacer avec des dispositifs extérieurs, via des ports d'entrée/sortie. Dans certaines architectures, les ports sont considérés simplement comme des cases de mémoire et ils sont gérés par les instructions de transfert (entrées/sorties intégrées mémoire). D'autres architectures disposent d'instructions spécifiques pour les entrées/sorties (entrées/sorties indépendantes).

Instructions de branchement

[modifier | modifier le code]

Il s'agit d'instructions qui altèrent le déroulement normal du programme. On distingue les sauts et les appels de routines :

  • les sauts provoquent un branchement du programme vers une adresse mémoire qui n'est pas contiguë à l'endroit où l'on se trouve ;
  • un appel de routine (call) (ou sous-programme) est un saut vers une partie du programme qui forme un bloc accomplissant une tâche donnée. Une routine permet ainsi de structurer le programme, et peut également être appelée à plusieurs reprises, voire des millions de fois, durant l'exécution du programme principal. La grande différence par rapport à un simple saut, c'est qu'au moment du branchement l'adresse de l'instruction suivante est mémorisée afin d'y revenir une fois la routine terminée.

Tant les sauts que les appels de routines peuvent être :

  • inconditionnels ;
  • conditionnels, c'est-à-dire que le branchement n'a lieu que si une certaine condition est remplie ; généralement, la condition testée est le contenu d'un des indicateurs d'état ; ceux-ci indiquent par exemple si le contenu de l'accumulateur est nul, positif, négatif, de parité paire ou impaire.

Instructions diverses

[modifier | modifier le code]

On trouve dans ce groupe :

  • des instructions de gestion de la pile (zone de mémoire RAM permettant le stockage de données locales des routines pendant l'exécution du programme) ;
  • des instructions de contrôle du processeur : par exemple passage en mode basse consommation, contrôle des périphériques embarqués (c'est-à-dire situés sur la même puce que le processeur) ;
  • des instructions permettant de positionner des indicateurs internes du processeur.

Références

[modifier | modifier le code]

Articles connexes

[modifier | modifier le code]

Bibliographie

[modifier | modifier le code]
  • Alan Turing, Jean-Yves Girard, La machine de Turing, Éditions du Seuil, [détail de l’édition] ; cet ouvrage comprend notamment une traduction en français (par Julien Basch et Patrice Blanchard) de l'article original, ainsi qu'une correction par Emil Post des erreurs y figurant.
  • (en) Alan Mathison Turing, On Computable Numbers, with an Application to the Entscheidungsproblem, vol. 2:42, coll. « Proceedings of the London Mathematical Society », (lire en ligne), p. 230-265.

Lien externe

[modifier | modifier le code]