Binaire après compilation ?
Résolu/Fermé- Impossible d'exécuter le fichier binaire : erreur de format pour exec()
- Erreur 0x80070643 - Accueil - Windows
- Fichier rar - Guide
- Format epub - Guide
- Impossible de supprimer un fichier - Guide
- Comment réduire la taille d'un fichier - Guide
14 réponses
12 janv. 2023 à 15:08
Bonjour,
Je pense avoir compris la question alors je me lance et on verra bien.
Réponse courte
- Générer un binaire obtenu à partir d'un code source sans s'appuyer sur un compilateur existant est faisable, mais très compliqué.
- Le format de binaire dépend du langage, et quand ce langage ne s'appuie pas sur machine virtuelle (comme c'est le cas pour Java ou C#), le code machine dépend du système d'exploitation et de son architecture logicielle. Cela qu'étend donné un code source, le binaire qui lui correspond n'est pas absolu.
- Si je devais écrire un compilateur générant un exécutable valide, je partirais du langage le plus bas niveau et donc le plus conforme du code machine qui sera traité par le CPU : l'assembleur. Car les compilateurs pour les autres langages (dits, de plus haut niveaux) sont bien plus compliqués.
Réponse détaillée
Le but d'un compilateur est de convertir un ou plusieurs fichiers texte qui contiennent du code source en code machine. Je dis code machine car tous les compilateurs n'ont pas la même cible :
- Un compilateur C, C++, fortran ou assembleur produit du code machine (binaire) conforme à l'architecture cible (par exemple amd64, i386, etc) et du système d'exploitation (Windows, Linux) pour laquelle il compile.
- Un compilateur java produit du bytecode qui est indépendant de la machine ou du système d'exploitation car il repose sur une machine virtuelle (il en irait de même pour C#) ;
- Je laisse volontaire de côté tous les langages pseudo interprétés (genre python ou julia)
Je me concentre maintenant uniquement sur la première catégorie car je pense que c'est celle qui t'intéresse. Le code machine produit dépend du système d'exploitation et de l'architecture cible
Comme le montre par exemple la page wikipedia sur ELF (donc qui suppose qu'on produit un exécutable pour Linux) on voit que l'en-tête de l'exécutable comporte des informations comme la taille d'une adresse mémoire (32 bits ou 64 bits, qui dépend du CPU) et de l'endianness (little endian ou big endian, qui dépend du CPU). Ces attributs caractérisent l'architecture cible dont je parlais.
Un compilateur C/C++ peut produire des binaires de différentes natures :
- des binaires de compilations intermédiaires (.o sous Windows et Linux)
- des exécutables (.exe sous Windows, pas d'extension sous Linux)
- des librairies dynamiques (.dll sous Windows, .so sous Linux)
- des librairies statiques (.lib sous Windows, .a sous Linux)
- des modules noyau (.ko sous Linux)
Ici je suppose que tu es plus intéressé par les exécutables, donc des binaires munis d'un point d'entrée (qui correspond à la fonction main si tu fais du C/C++). Ça tombe, l'adresse du point d'entrée est renseignée dans l'en-tête ELF, donc quand le système doit exécute un tel binaire, il sait par où commencer.
Toutes les informations dans l'en-tête ELF vont permettre au système d'exploitation de s'appuyer sur les librairies adéquates (en particulier la librairie C ou C++ si le programme est écrit en C/C++). Car oui, il est important de signaler qu'un exécutable n'est en général pas purement autonome et s'appuies sur les librairies du système (par exemple, le code machine associé à la fonction printf est dans la libc, pas dans ton programme). On peut retrouver à quelles librairies un exécutable est lié avec la commande ldd sous Linux.
Si ensuite tu veux creuser plus sur le format ELF, tu peux regarder la commande readelf qui permet d'examiner un binaire arbitraire pour comprendre comment il est organisé. Je ne peux pas l'affirmer mais j'imagine qu'en gros, tu vas ensuite avoir une section en assembleur pour chaque fonction embarquée dans le binaire.
Donc tout le but du jeu est de savoir retranscrire une fonction (écrite en C, si le langage de départ est le langage C) au format assembleur correspondant à l'architecture cible (je t'invite donc à lire cette page pour comprendre ce que contient ton .exe). Comme l'assembleur est un langage très bas niveau, écrire un programme aussi simple qu'écrire un hello world est extrêmement fastidieux à écrire. Moins de en moins de monde sait coder en assembleur et la plupart des gens s'appuient sur les librairies existantes.
En suite supposons que ton programme contienne du code simple à restranscrire en assembleur (par exemple un calcul mathématique impliquant des opérations de bases). Pour traduire le programme C en assembleur, le compilateur doit tout d'abord faire une analyser syntaxique selon la grammaire (au sens de la théorie des langages) définie par le langage de départ. Si tu veux en savoir plus à ce sujet tu peux regarder yacc et bison. De là, le compilateur peut se faire une représentation en mémoire de ce que fait le programme (par exemple à l'aide de structures de données si le compilateur est lui même codé en C). De cette représentation, le compilateur va retranscrire le code assembleur et l'écrire au bon endroit du fichier ELF en cours de production.
Et là vient inévitablement la question, comment a été écrit le premier compilateur (car si on prend gcc, le compilateur C, c'est lui même un exécutable qui s'appuie... sur la lib C). On se demande donc qui de l'œuf et de la poule est né le premier. J'imagine qu'au début il a fallu se débrouiller en assembleur pur. Toujours est-il que de nos jours, on construit les nouveaux compilateurs et les nouvelles lib C en s'appuyant sur les compilateurs et (donc llb C) antérieurs.
J'espère que ces quelques éléments t'aideront.
Bonne chance
Bravo mamiemando, je n'aurais pas eu la patience d'écrire tout cela.
Un peu d'histoire.
La compagnie Control Data Corporation avait un compilateur Fortran IV qui s'appelait "run" et qui traduisait directement du source Fortran IV en code machine pour les machines de la série CDC 6000 dans les années 1960 et au début des années 1970.
Le compilateur était lui-même écrit en assembleuret on avait accès au source du compilateur.
J'ai connu un compilateur Pascal évidemment écrit en Pascal mais dont on avait remplacé les mots-clés anglais par des mots -clés français.
Bien sûr, il a fallu recompiler le compilateur pour qu'il fonctionne en français.
13 janv. 2023 à 15:09
Merci pour le compliment ; et pour les rappels historiques, dont je n'avais pas connaissance ;-)
Pas certain de ce que tu veux savoir. C'est un sujet complexe.
On écrit d'abord un programme dans un langage "symbolique" comme C ou C++ etc.
Le "compilateur" est un programme qui reconnait les instructions données dans le programme et les traduit, comme tu dis, en "binaire".
C'est à dire une suite de codes reconnaissables par le processeur et exécutées directement.
Sur Windows, le compilateur génère automatiquement un fichier avec l'extension .exe. Tu n'as pas besoin de mentionner l'extension.
Ah d'accord merci. Mais dans ce cas, comment faire un .exe sur Windows ?
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionModifié le 28 déc. 2022 à 16:25
Bonjour,
on n'écrit jamais du binaire dans un fichier, ce serait infernal comme boulot !
(tu saurais faire ça, toi ?)
on écrit du code dans un fichier ascii dans un langage de haut niveau compréhensible par un humain
(en général les instructions sont des mots anglais) et grâce à un logiciel appelé compilateur, on génère
le fichier .exe
D'accord mais comment créer le fichier .exe? Quoi mettre dedans ?
28 déc. 2022 à 19:38
ouh là là !
il va falloir revoir les bases dis-donc !
tu n'as pas compris ce qu'on t'a raconté avant ?
je répète:
1_ on écrit le code désiré avec un langage de haut niveau dans un fichier texte (test.c)
exemple avec le langage C:
#include <stdio.h> #include <string.h> int main() { printf("Hello !"); return 0; }
2_ on compile ce fichier avec un compilateur, par exemple gcc, en tapant la commande
gcc c:\progc\source\test.c -o c:\exe\test.exe -lm -lalleg
dans l'invite de commande Windows
Le résultat est un fichier test.exe qui est exécutable et qui donne ce résultat:
Ce n'est pas toi qui crée le fichier binaire, c'est le compilateur et il le fait à partir du programme écrit en langage "source" ou "symbolique".
Quand tu manges, ton estomac digère les aliments pour extraire des nutriments.
Ce n'est pas toi qui assimile des nutriments directements.
C'est la même chose pour le compilateur, il "digère" le code source.
Oui j'ai compris ça. Mais comment fait il justement pour créer le fichier binaire ?
2 janv. 2023 à 00:40
en python, par exemple:
f = open("pr.exe", "wb") f.write(b'423') f.close()
Le code source est le nom du programme écrit dans un langage "symbolique" que l'on fait compiler pour le retrouver dans le .exe.
Les programmes "libres": On peut télécharger le code source et le compiler sois-même si l'on veut. Sinon faut écrire toi-même ton code-source.
https://www.journaldunet.fr/web-tech/dictionnaire-du-webmastering/1203623-code-source-definition-traduction/
A quoi ressemble le code-source de la page web de ccm que tu es en train de lire?
clique droit dans la page puis clique sur "code source de la page"
S'affiche le code source non exécuté de la page avec des numéros de lignes du texte en langage "symbolique" des jolies couleurs pour faciliter la lecture.
Mais du coup, les créateurs du compilo doivent savoir coder en binaire ?
les créateurs du compilo doivent savoir coder en binaire ?
Même réponse:Tu pourrais mais c'est un boulot infernal. Exemple: le compilateur gcc est écrit en langage C.
GCC
Il s'agit d'un compilateur multiplateformes, incontournable sur les systèmes Unix et reconnu notamment pour son respect des standards. Il est fourni sous forme de sources et se compile avec le compilateur C existant du système.
L'explication du codage en binaire qu'il faudrait faire si on codait pas en C pour ce compilateur:
Modifié le 28 déc. 2022 à 19:19
Salut,
déjà, faute de compréhension : le binaire n'est pas un langage, c'est la façon d'écrire des nombres en base 2.
Un compilateur va interpréter les instructions d'un langage de haut niveau, type C pour les transformer en langage machine, qui est le seul langage compréhensible directement par le processeur.
Là où est la confusion, c'est que les instructions en langage machine sont codées par un nombre en binaire dans le processeur.
Ex : l'instruction "NOP" (qui ne fait rien) présente dans le processeur est codée sous la forme 10010000 (0x90 en hexadécimal), donc quand il voit arriver la suite de bits 10010000, il sait qu'il doit exécuter "NOP".
La liste des instructions ici :
https://en.wikipedia.org/wiki/X86_instruction_listings
Donc oui, pour écrire un compilateur, il faut avoir une connaissance approfondie du processeur sur lequel tourneront les programmes...
Donc, quand tu ouvriras un .exe dans un éditeur de texte, tu verras des paquets de bytes (selon le processeur, les instructions sont sur 8, 16, 32 ou 64 bits...) qui correspondent aux instructions natives du processeur.
Tu peux même utiliser un désassembleur/décompilateur qui va traduire le .exe en assembleur (qui est le langage qui s'apparente le plus au langage machine) ou en C.
28 déc. 2022 à 18:46
Ah. Donc le compilateur, codé en C, par exemple, va écrire un fichier (.exe) en language machine (celui du processeur) à base du code source ?
28 déc. 2022 à 18:56
oui
Je crois que tu veux aller trop loin. Qui vient en premier, la poule ou l'oeuf?
Les premiers compilateurs ont été écrit en "assembleur" qui est également un langage symbolique.
Qui a écrit le premier assembleur? Hé bien, ça été effectivement écrit en "binaire" sur des cartes perforées ou des rubans perforés il y a plus de 60 ans ...
2 janv. 2023 à 00:30
bonjour,
En effet, il suffit d'écrire dans un fichier. A condition, évidemment, de savoir qu'y écrire.
C'est, d'ailleurs vrai pour n'importe quel fichier, que ce soit un exe ou un document Word.
2 janv. 2023 à 00:54
Ta question est extrêmement imprécise.
Veux-tu savoir comment créer un fichier exécutable? Le format du fichier exécutable dépend de l'OS (Windows, Linux, ...) ainsi du type de processeur (Intel, ARM, ...) et d'adressage (32 ou 64 bits, le plus souvent).
Pour te donner une vague idée de ce que contient un exécutable: https://fr.wikipedia.org/wiki/Portable_Executable Comme souvent, les articles en anglais sont plus précis.
Oui merci beaucoup désolé pour mon retard. Tu as vraiment bien détaillé, merci beaucoup, vraiment. Merci egalement pour les infos historiques!
13 janv. 2023 à 20:39
Pr.Witherfire == JamesMcHarson ?
Est-ce que tu as toutes les réponses à tes questions. Si oui, pouvons-nous basculer le sujet en résolu ?
14 janv. 2023 à 14:34
Bonjour.
Pareil que toi;) :
Réponse courte:
Oui, Oui, Oui.
Réponse détaillée:
J'avais des problède de mdp, Pr.Witherfire est mon vrai compte, désolé de m'etre emmelé les pinceaux.
Oui, j'ai toutes les réponses à mes questions, vous m'avez d'ailleurs trés bien repondu, merci.
Je vais basculer le sujet en résolu.
;)
Merci à tous et peut etre toutes d'ailleurs.
Au revoir
Modifié le 17 janv. 2023 à 16:32
Il faut un compte CCM administrateur ou être authentifié avec le compte CCM qui a ouvert la question. Apparemment quelqu'un s'en est déjà occupé. Bonne continuation !
17 janv. 2023 à 17:44
Ok merci ( c'est peut être à cause du fait que je me suis connecté sans compte?) Au revoir