Langage compilé aide

Fermé
Utilisateur anonyme - 17 oct. 2014 à 13:24
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 - 19 oct. 2014 à 10:55
Bonjour sur comment ca marche dans langage il y a ca : Un programme écrit dans un langage dit « compilé » va être traduit une fois pour toutes par un programme annexe, appelé compilateur, afin de générer un nouveau fichier qui sera autonome , je voulais savoir si le compilateur transforme le programme ecrit dans un langage de programmation dans le langage binaire? si qui créé le programme?

3 réponses

Utilisateur anonyme
17 oct. 2014 à 13:36
Bonjour. Le programmeur écrit dans un certain langage humainement compréhensible, et le programme de compilation va "traduire" le programme en langage machine.
Attention, on parle de codage binaire, pas de langage.
0
Utilisateur anonyme
17 oct. 2014 à 18:58
oui mais le compilateur cree le programme en codage machine?
0
oui, un compilateur "transforme" le langage évolué en une série d'instructions bas niveau ( interruptions micro processeur, registres ), il y a plusieurs types d'instructions entendables par le microprocesseur, soit des instructions RISC ou CISC, VLIW, vectorielles, dataflow ( lié à l'architecture du processeur ). Pour te faire une idée plus précise je t'invite à un peu de lecture

https://fr.wikipedia.org/wiki/Instruction_informatique
https://fr.wikipedia.org/wiki/Architecture_de_processeur

Cdt
0
Utilisateur anonyme
17 oct. 2014 à 19:43
ok donc le programme et en binaire grace au compilateur?
0
Utilisateur anonyme
17 oct. 2014 à 19:50
C'est ce qu'on te dis...
0
Utilisateur anonyme
17 oct. 2014 à 20:00
je sais pas si c'est moi mais je trouve que wikipedia ne met pas trop de details et parfois emploi des mots que tout le monde ne peux pas comprendre
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
17 oct. 2014 à 22:14
Bonjour,

Un compilateur transforme un fichier relativement verbeux, en un ou plusieurs autres fichiers plus concis et technique, mais ce n'est pas toujours du langage machine.

On peut par exemple avoir des langages pour lesquels la phase de compilation consiste à réécrire le code en un autre langage qui sera ensuite recompilé ou interprété.

Exemple : les codes en Java, Scala, Groovy, etc. sont compilés en Bytecode, qui est un langage intermédiaire, pouvant être interprété par la machine virtuelle Java, recompilé pour la plateforme Android, et plus rarement transformé en code machine.

Il faut d'ailleurs faire la distinction entre le code compilé et interprété.
Interprété : ton code sera lu tel quel à chaque fois, s'il y a une erreur on ne le saura que quand on tombera dessus (c'est le cas par exemple des pages web).
Compilé : il y a une phase de réécriture qui permet de garantir qu'un certain nombre d'erreurs (notamment de syntaxe) ont été éliminées

Autre caractéristique : la compilation entraîne une perte d'information, il est impossible de retrouver le code exact avant compilation, tout au plus on retrouvera un code équivalent qui se compilera de la même manière.
0
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 138
Modifié par nicocorico le 19/10/2014 à 11:01
Oui c'est ça, seul le langage compilé est réellement exécuté, tandis que l'interprété est lu par le programme d'interprétation du bytecode.

Pour bien cerner tout ça, il faut comprendre ce que signifie "exécuter", qui est, je trouve, un terme un peu dur pour décrire un principe plus passif qu'on pourrait le croire!
En fait pour mieux se représenter il faut revenir à la racine de l'ordinateur, c'est à dire aux rubans perforés:


Sur ce ruban, pour chaque ligne on a 8 positions pouvant chacune être percée ou non, permettant de dire oui ou non, blanc ou noir, 0 ou 1, ou bien -en considérant l'ensemble de ces 8 bits- une valeur de 0 à 255 (2^08)... tout dépend du sens qu'on lui donne.
Autrement dit, chaque ligne donne un ensemble de valeur 0 ou 1 qu'on interprète de différentes manières en fonction des besoins.
Ce peut être un numéro ascii décrivant une lettre, le ruban décrivant alors un texte..
Ou le niveau de gris de chaque point d'une image en noir et blanc...
Ou encore un relevé de température jour après jour.
C'est tout ce que l'on veut, selon les besoins!

Autrement dit c'est un fichier binaire, pouvant être de n'importe quel type...
Et ce ruban est une mémoire informatique, en tous points!
La révolution du ruban, c'est qu'il permet de donner toute une liste à une machine, et pas seulement deux valeurs! On peut donc automatiser le calcul, en fournissant une liste de données à traiter;

Alors maintenant, imaginons que l'on veuille appliquer un calcul aux valeurs qu'on va lire à partir du ruban;
Admettons que l'on souhaite multiplier les valeurs lues deux à deux , en ce cas, on va fabriquer une machine qui multiplie deux à deux.

Ensuite on veut additionner. On va créer une machine qui additionne les valeurs deux par deux.
Pareil avec la soustraction et la division.
Et si on souhaite diviser deux à deux, puis additionner avec la troisième, il faudra également concevoir une nouvelle machine!
Autrement dit, pour chaque traitement de données sur base de ce ruban, on devra créer une machine qui fait ça et que ça. Sans aucune souplesse possible!
On a donc assoupli l'alimentation en données, on peut choisir chaque valeur et on peut faire les opérations de base, mais le type de traitement est resté rigide, rendant cette machine peu pratique et loin de ses promesses!

Mais eurêka!
On a un ruban avec les données, et on sait concevoir les machines qui font différents calculs basiques, alors pourquoi ne pas ajouter un second ruban pour donner à chaque pas une valeur définissant quelle machinerie doit être utilisée pour le calcul, et donc, de facto, quel calcul on va appliquer sur les données?

Ainsi, on a la possibilité de dire à chaque pas ce que l'on souhaite faire des valeurs à venir, en définissant simplement une valeur pour chaque opération.
Donc un second ruban contient une liste de valeurs de 0 à 3 qui indique laquelle des quatre opérations il faut appliquer, permettant d'automatiser des calculs plus compliqués. Cette valeur s'appelle une instruction, puisqu'elle donne une instruction au processeur.

Ensuite, pour assouplir encore, on ajoute d'autre possibilités à ces instructions, et surtout certaines possibilités cruciales : le fait de pouvoir comparer deux valeurs, et de passer à une ligne spécifiée selon le résultat de cette comparaison!
Grâce à ce mécanisme on peut influencer le cours du programme en fonction des valeurs qu'il rencontre, ce qui permet de bâtir des algorithmes!
On ajoute aussi la possibilité d'y insérer des données, ainsi on agrémente les instructions de valeurs constantes telles qu'une nouvelle position d'exécution, ou une opérande utile pour un calcul, ou encore une position à lire sur le ruban de données, sans pour autant devoir les stocker systématiquement dans la zone de donnée elle-même.


Tu l'auras compris, le second ruban est le ruban.. de programme! On exécute le programme qui s'y trouve!
C'est un ruban similaire au ruban de données, mais les valeurs qu'il contient on une signification précise et cohérente pour la machine, qui deviendra ensuite le surpuissant processeur!

En pratique, tout processeur retient la position de son ruban-programme, sous forme de pointeur de code.
Ce pointeur de code suit simplement le cours de l'exécution en passant à l'instruction suivante à chaque pas, sauf lorsqu'il rencontre une instruction de saut venant le placer à un autre endroit, que ce soit le point d'entrée d'une fonction ou un point fermant la boucle d'un algo.

Le ruban a laissé place aux bandes magnétiques, puis aux mémoires à base de tubes puis de transistors, permettant de libérer le processeur de la contrainte de la position du ruban ou de la bande, beaucoup trop lent!
Par contre côté stockage, le ruban est toujours là! Les disques durs et les disques optiques sont des rubans.. circulaires! Le principe est strictement le même -si ce n'est que le ruban n'était pas réinscriptible- et on en retrouve d'ailleurs les contraintes de temps d'accès!


Donc, ce qu'il faut comprendre en résumé: un programme est constitué de valeurs ayant un sens précis pour le processeur, et il se "contente" de lire ces valeurs et d'appliquer l'opération que lui ordonne chacune de ces instructions. Les programmes cohabitent en mémoire avec les données, mais certains mécanismes empêche d'exécuter par erreur une zone de données, puisqu'elles ne sont pas cohérentes évidemment, et pousseraient le processeur à faire n'importe quoi! Mais le programme n'est toujours resté qu'une liste de données, et il est d'ailleurs très simple de le modifier avant de l'exécuter, autorisant de tailler une routine de calcul spécifique pour chaque cas rencontré.

Et sur cette base, on imagine bien que le processeur donne un sens précis à chaque valeur d'instruction, et que le programme est écrit en en tenant compte!
Or, les listes d'instructions d'un processeur de pc, d'un powerpc, d'un 6809 ou d'un processeur de smartphone ne sont pas du tout équivalentes!
Donc une même valeur n'aura pas le même sens pour un processeur ou l'autre, et leur logique de fonctionnement connait des variations également, rendant totalement incompatible avec les autres le programme écrit pour l'un.

Le bytecode lui, n'est pas une instruction au sens du processeur, mais elle en est une pour le programme qui la lit! En fait l'interpréteur simule le fonctionnement d'un processeur, lisant les valeurs et s'appliquant à obéir aux ordres listés, simplement les bytecode font des choses un peu plus évoluées de manière à compenser le fait que l'interpréteur consomme du temps de calcul. Plus le bytecode remplace un ensemble important d'instructions, moins le coût de son interprétation est élevé.
Donc dans ce cas, le bytecode n'est jamais lu par le processeur (qui ne peut le comprendre de manière cohérente) mais par l'interpréteur, et c'est le programme de cet interpréteur qui est lu par le processeur. Exécuté...

Voici un exemple de programme assembleur x86 :
Les variables eax et ecx s'appellent des registres, ce sont des zones mémoires nommées, sur lesquelles s'appliquent les instructions avec plus d'efficacité qu'en mémoire.

      Mov  eax, 10      // eax contient 10
Mov ecx, 5 // ecx contient 5
@Bcl: Imul eax,eax // Mutltiplie eax par lui-même
Dec ecx // Soustrait 1 à ecx
Jnz @Bcl // Saute au label "@Bcl" seulement si ecx est supérieur à zéro.

// Si ecx vaut 0, le programme continue son cours ici, et sort donc de la boucle.


Ici, on boucle 5 fois la multiplication d'eax par lui-même, c'est à dire qu'on calcule eax^6, donc 10^6.

En version compréhensible par le processeur -sur notre ruban perforé donc- voici ce que ça donne:
(en hexadécimal, identique au binaire mais bien plus lisible)

$B80A000000     Mov  eax, 10      
$B905000000 Mov ecx, 5
$0FAFC0 Imul eax,eax
$49 Dec ecx
$75FA Jnz @bcl;


Ces codes barbares sont donc ceux qui sont gravés dans le processeur comme ayant une certaine fonction, et déclenchent la réaction attendue.
Sans surprise, on donne ces codes hexadécimaux à mouliner au proc, et il calcule juste et bien!

Les processeurs actuels peuvent démêler une telle boucle un bon milliard de fois par seconde.

Le chêne aussi était un gland, avant d'être un chêne
0