Rechercher

Vous pouvez entrer une phrase pour rechercher sur tout le site.

Accueil

Hardware

Software

Pas à pas

Internet

Le site

Contacts


Partenaires

Les bases de la programmation - page 1

  Cet article a été écrit dans un but: vous initier au fonctionnement des programmes, et d'un système d'exploitation, en mettant en avant le coté fonctionnement des programmes, et en explicitant quelques langages très utilisé: le langage machine, l'assembleur, le C et deux langages interprétés: le Perl, et le PHP. Vous ne trouverez pas ici une initiation à la programmation dans ces langages, mais bien une explication de fonctionnement.

1. Processeurs, langage machine, assembleur

La numération binaire.
  En binaire, les nombres ne sont représentés que par des 0 ou des 1. Dans la pratique, comme 1 caractère hexadécimal représente exactement 4 caractères binaires, on représente majoritairement toutes les données en hexadécimal, en préfixant 0x devant. Ainsi 0b01001101 = 0x4D.
Une autre chose importante est la notion de bits de poids fort, ou de poids faible. Si l'on considère un octet (8 bits) par exemple, le bit de poids fort sera celui le plus à gauche.
Enfin, en informatique, 8 bits sont un octet (un byte), 2 octets sont un mot (word), 4 octets forment un double mot (dword) et 8 octets un quadruple mot (qword).

Les processeurs.
  Il existe un grand nombre de familles de processeurs différentes (x86, Sparc, alpha, ...), mais seul une d'entre elles est actuellement représentée dans les ordinateurs personnels: les x86. Il s'agit du nom générique des processeurs Intel (et AMD).
A l'origine fut le Intel 8086, premier processeur x86. Dans ce processeur apparurent toutes les instructions élémentaires, et qui pour des raisons de compatibilités sont encore exactement les mêmes aujourd'hui. Puis il y a eu les 80186, et 80286.
Enfin, il y a eu le i386: c'est le premier processeur complet, et qui est resté longtemps la base de compatibilité des programmes. Puis il y a eu le 486, à l'époque où les ordinateurs personnels se sont vraiment développé; puis il y a eu le 586, plus connu sous le nom Pentium, et enfin le i686, qui comprend les Pentiums PRO, II, III, IV et Celeron.
Pour bien comprendre à quoi correspond tout cela, il faut comprendre le processeur.
Le processeur est un composant électronique qui exécute des instructions élémentaires (voir l'article sur le processeur. De façon évidente, pour qu'un programme puisse marcher avec un processeur, il faut que les instructions utilisées par ce programme soient des instructions que le processeur comprenne.
Ainsi, i383, i586 et i686 définissent des jeux d'instructions standard. C'est à dire qu'un processeur (par exemple un i686) comprendra toutes les instructions définies par i686, et surtout les appellera par le même nom. Et même si un processeur i686 tel que le Pentium IV comprend plus d'instructions que le Pentium II, ils auront au moins en commun les instructions minimales d'un i686.

Par la suite, nous nous retreindrons aux processeurs i386 et plus, et nous considérerons que les processeurs sont 16bits (ce n'est pas vrai pour les Pentium et plus, mais cela simplifiera, sans rendre l'explication fausse pour autant).

Le langage machine.
  Le processeur récupère les instructions qu'il exécute. Etant un circuit électronique, il n'est capable de recevoir des informations que sous la forme binaire. Et donc les instructions qu'il comprend sont en fait des instructions écrites en binaire. Et le processeur étant dit "16 bits", chaque instruction a une taille qui fait un multiple de 16bits. Par exemple, 0x01D8 représente l'instruction basique d'addition entre les registres AX, et BX.
Pour résumer, le langage machine est la représentation exacte des instruction qui seront exécutées telles quelles par le processeur.

L'assembleur.
  Mais le langage machine est totalement incompréhensible, car les bits codant une instruction sont quasiment sans signification.
Pour pallier à cela on utilise un système de mnémonique. En langage assembleur, chaque instruction est remplacée par un mnémonique, les registres sont nommés, mais les adresses mémoires sont représentées directement par leur valeur hexadécimale. Par exemple, le mot 0x8A03 sera écrit de façon plus simple en langage assembleur mov AL,[BP+DI], qui est clairement plus compréhensible (pour information, cette instruction copie dans les 8 bits AL de poids faible du registre AX 8 bits de données provenant de l'adresse mémoire ES:BP+DI).
Il est ainsi beaucoup plus facile pour un programmeur de travailler sur l'assembleur, d'autant qu'il permet d'écrire des programmes beaucoup plus rapides qu'avec d'autres langages. L'assembleur simple n'est néanmoins pas parfait: supposons que l'on veuille effectuer un saut. C'est à dire que l'on veut aller autre part dans le programme en sautant des instructions. On va alors utiliser l'instruction jump near 76F3 (near fait référence à la distance de là où on veut aller, et 76F3 est l'adresse mémoire où l'on doit aller).
C'est à dire que l'on doit savoir précisément où se trouve l'instruction où l'on veut sauter ...

L'assembleur évolué.
  On a donc étendu l'assembleur. Au lieu de faire de l'assembleur qui, par une simple traduction du code assembleur en langage machine donne un programme fonctionnel, on passe par un assembleur nommé: on donne des noms aux objets, et on identifie par la suite les objets par leur nom et non par leur adresse mémoire.
Par exemple, dans le cas de notre saut, on peut placer une étiquette (label) avant l'instruction où l'on va vouloir sauter: onveutallerla: . Puis pour notre saut, on écrira jump onveutallerla. La programmation en est d'autant plus facile, surtout que le saut n'est qu'un exemple où l'assembleur évolué est d'une grande aide.
Mais maintenant, pour obtenir un programme en langage machine (et donc compréhensible par le processeur), on ne peut plus simplement se contenter de traduire cet assembleur en langage machine. On utilise alors un compilateur. Le travail d'un compilateur (n'importe quel compilateur) est de transformer du code source (c'est à dire un fichier texte décrivant le fonctionnement du programme) en un programme qui marche.
Dans le cas de l'assembleur, la compilation reste simple, puisque il s'agit majoritairement de traduire, et de remplacer les noms. Pour cela, le compilateur va calculer l'adresse mémoire où sera chaque instruction, et remplacera de fait le jump onveutallerla par jump near xxxx avec xxxx l'adresse de l'instruction qui suit notre étiquette onveutallerla: .
L'assembleur évolué offre aussi beaucoup d'autres fonctionnalités, telles que les macros, la gestion simplifiée des piles, ...
Cela fait maintenant longtemps que plus personne ne travaille en assembleur simple sur les i386, car l'assembleur évolué permet d'obtenir exactement la même chose au final, tout en ayant la tâche simplifiée.

Conclusion.
  L'assembleur est un langage extrêmement puissant, dans le sens où l'on contrôle par soi-même ce que le processeur fera. On a aussi un accès direct à la mémoire. Mais il y a plusieurs défauts.
D'une part le jeu d'instructions d'un processeur est assez limité. Il faut par exemple une vingtaine d'instructions pour afficher un caractère a l'écran ... Ces instructions sont de plus extrêmement sommaires (opération mathématiques de base, opérations logique, opération simple sur la mémoire, et opération de contrôle du programme: saut, saut conditionnels, appels a des interruptions (appels au matériel), et autres opérations destinées à contrôler le processeur).
L'assembleur est donc très puissant, très rapide, mais trop simple (donc compliqué à utiliser pour faire des choses complexes).

 

Suite page 2

Valid XHTML 1.1! Valide CSS!

Hit-Parade

Mesurez votre audience

Copyright © 2000 - 2008 World-Informatique.com. Tous droits réservés.
Hébergement offert par OVH