Code assembleur vs code machine vs code objet?

227

Quelle est la différence entre le code objet, le code machine et le code assembleur?

Pouvez-vous donner un exemple visuel de leur différence?

mmcdole
la source
Je suis également curieux de savoir d'où vient le nom du "code objet"? Que signifie le mot «objet» en lui? Est-ce en quelque sorte lié à la programmation orientée objet ou simplement à une coïncidence de noms?
SasQ
@SasQ: code objet .
Jesse Good
Je ne demande pas ce qu'est un code objet, capitaine Obvious. Je demande d'où vient le nom et pourquoi est-il appelé code "objet".
BarbaraKwarc

Réponses:

296

Le code machine est un code binaire (1 et 0) qui peut être exécuté directement par la CPU. Si vous deviez ouvrir un fichier de code machine dans un éditeur de texte, vous verriez des ordures, y compris des caractères non imprimables (non, pas ces caractères non imprimables;)).

Le code objet est une partie du code machine qui n'a pas encore été liée à un programme complet. C'est le code machine d'une bibliothèque ou d'un module particulier qui constituera le produit terminé. Il peut également contenir des espaces réservés ou des décalages non trouvés dans le code machine d'un programme terminé. L' éditeur de liens utilisera ces espaces réservés et décalages pour tout connecter ensemble.

Le code d'assemblage est un code source en texte clair et (quelque peu) lisible par l'homme qui possède principalement un analogue 1: 1 direct avec des instructions machine. Ceci est accompli en utilisant des mnémoniques pour les instructions réelles, les registres ou d'autres ressources. Les exemples incluent JMPet MULTpour les instructions de saut et de multiplication du CPU. Contrairement au code machine, le CPU ne comprend pas le code assembleur. Vous convertissez le code assembleur en machine à l'aide d'un assembleur ou d'un compilateur , bien que nous pensions généralement aux compilateurs en association avec un langage de programmation de haut niveau qui sont plus loin des instructions CPU.

La construction d'un programme complet implique l'écriture du code source du programme dans un assembly ou un langage de niveau supérieur comme C ++. Le code source est assemblé (pour le code assembleur) ou compilé (pour les langages de niveau supérieur) en code objet, et les modules individuels sont liés entre eux pour devenir le code machine du programme final. Dans le cas de programmes très simples, l'étape de liaison peut ne pas être nécessaire. Dans d'autres cas, comme avec un IDE (environnement de développement intégré), l'éditeur de liens et le compilateur peuvent être appelés ensemble. Dans d' autres cas, un compliqué make script ou solution fichier peut être utilisé pour indiquer l'environnement comment construire l'application finale.

Il existe également des langages interprétés qui se comportent différemment. Les langages interprétés reposent sur le code machine d'un programme d'interpréteur spécial. Au niveau de base, un interpréteur analyse le code source et convertit immédiatement les commandes en nouveau code machine et les exécute. Les interprètes modernes, parfois également appelés environnement d'exécution ou machine virtuelle , sont beaucoup plus compliqués: évaluer des sections entières de code source à la fois, mettre en cache et optimiser si possible et gérer des tâches complexes de gestion de la mémoire. Un langage interprété peut également être précompilé en un langage intermédiaire ou un bytecode de niveau inférieur, semblable au code assembleur.

Joel Coehoorn
la source
24
+1: réponse agréable, mais quelque peu simplificatrice - toutes les instructions d'assemblage ne sont pas traduites 1: 1 en instructions machine, et les fichiers objets peuvent également contenir d'autres données (informations de relocalisation, tables de symboles, ...)
Christoph
5
Ajout d'un mot belette pour votre premier numéro, modifié pour rendre le 2e plus clair.
Joel Coehoorn
2
@Christoph: vous dites "toutes les instructions de montage ne sont pas traduites 1: 1 en instructions machine", veuillez donner un exemple.
Olof Forshell
5
@Olof: les architectures RISC fournissent parfois un jeu d'instructions virtuel au niveau de l'assemblage - par exemple les pseudo-instructions MIPS ( en.wikipedia.org/wiki/MIPS_architecture#Pseudo_instructions )
Christoph
3
@Panzercrisis Rien n'est ajouté par l'assembleur. C'est une traduction directe de ce que vous avez écrit en instructions machine réelles. Et je n'appellerais pas le code supplémentaire mis par les compilateurs "inutile"
Joel Coehoorn
125

Les autres réponses ont donné une bonne description de la différence, mais vous avez également demandé un visuel. Voici un diagramme montrant qu'ils passent du code C à un exécutable.

Graphics Noob
la source
3
Je trouve cela vraiment utile, mais il manque l'étiquette "Code machine"
Alexx Roche
Donc, quand il est au niveau du code exécutable, est-ce équivalent au code machine?
CMCDragonkai
3
Dans le cadre de ce diagramme, le "code objet" est le code machine.
Graphics Noob
5
En fait, le code objet et le code exécutable sont tous deux des codes machine. la différence est que le code objet n'est pas le programme terminé. Il doit être combiné avec d'autres codes de bibliothèque / module d'assistance comme indiqué dans le diagramme pour former un programme / code exécutable complet.
okey_on
@okeyxyz à quel niveau serait-il correct de dire qu'il est directement exécuté par le processeur? Après l'assembleur, après l'éditeur de liens, après le chargeur, après sa conversion en microcontrôleur?
Celeritas
49

Le code d'assemblage est une représentation lisible par l'homme du code machine:

mov eax, 77
jmp anywhere

Le code machine est un code hexadécimal pur:

5F 3A E3 F1

Je suppose que vous voulez dire du code objet comme dans un fichier objet. Il s'agit d'une variante du code machine, à la différence que les sauts sont en quelque sorte paramétrés de sorte qu'un éditeur de liens puisse les remplir.

Un assembleur est utilisé pour convertir le code assembleur en code machine (code objet) Un éditeur de liens relie plusieurs fichiers objet (et bibliothèque) pour générer un exécutable.

J'ai écrit une fois un programme d'assembleur en hexadécimal pur (aucun assembleur disponible) heureusement, c'était bien le bon vieux (ancien) 6502. Mais je suis content qu'il y ait des assembleurs pour les opcodes pentium.

Toon Krijthe
la source
76
Non Non Non Non. Le code machine n'est pas un code hexadécimal. c'est du pur binaire. Le code hexadécimal n'est qu'une représentation pratique du binaire.
Breton
56
Si nous allons vraiment dans des extrêmes, ce n'est pas binaire, c'est une quantité d'électricité stockée dans un circuit. ;-)
Toon Krijthe
17
Oui bien sûr. Il existe une relation entre l'hexidécimal et ce que vous appelleriez le "code machine", mais il n'est pas tout à fait exact de dire que l'hexidécimal est le code machine. C'est tout ce que j'essaie de dire.
Breton
9
@Breton En ce sens, le "code hexadécimal" n'existe pas? Le «code hexadécimal» n'est qu'un moyen de visualiser le code machine. Vous pouvez afficher le code machine en hexadécimal, binaire, octal, décimal ou comme vous le souhaitez. Toujours dans ce sens, il n'y a pas non plus de "code binaire". Encore une fois, le "code binaire" n'est qu'un moyen de visualiser le code machine.
Utku
9
@Breton Ce que vous dites n'a pas vraiment de sens. Le binaire est un moyen de représentation, tout comme l'hex. S'il n'est pas hexadécimal, il n'est pas non plus binaire.
Koray Tugay
18

8B 5D 32 est le code machine

mov ebx, [ebp+32h] est l'assemblage

lmylib.socontenant 8B 5D 32est le code objet

Quassnoi
la source
8

Un point non encore mentionné est qu'il existe différents types de code d'assemblage. Dans la forme la plus élémentaire, tous les nombres utilisés dans les instructions doivent être spécifiés sous forme de constantes. Par exemple:

1902 $: BD 37 14: LDA 1437 $, X
1905 $: 85 03: STA 03 $
1907 $: 85 09: STA 09 $
1909 $: CA: DEX
190 $ A: 10 $ BPL 1902 $

Le bit de code ci-dessus, s'il est stocké à l'adresse 1900 $ dans une cartouche Atari 2600, affichera un certain nombre de lignes de différentes couleurs extraites d'une table qui commence à l'adresse 1437 $. Sur certains outils, taper une adresse, ainsi que la partie la plus à droite de la ligne ci-dessus, stockerait en mémoire les valeurs affichées dans la colonne du milieu et commencerait la ligne suivante avec l'adresse suivante. Taper du code sous cette forme était beaucoup plus pratique que taper en hexadécimal, mais il fallait connaître les adresses précises de tout.

La plupart des assembleurs permettent d'utiliser des adresses symboliques. Le code ci-dessus serait écrit plus comme:

rainbow_lp:
  lda ColorTbl, x
  sta WSYNC
  sta COLUBK
  dex
  bpl rainbow_lp

L'assembleur ajusterait automatiquement l'instruction LDA afin qu'elle se réfère à n'importe quelle adresse mappée à l'étiquette ColorTbl. L'utilisation de ce style d'assembleur facilite beaucoup l'écriture et la modification du code qu'il ne serait possible si l'on devait saisir et maintenir à la main toutes les adresses.

supercat
la source
1
+1. Un autre point supplémentaire: il existe également différentes syntaxes de langage d'assemblage , les plus célèbres étant Intel et AT&T .
informatik01
1
@ informatik01: Que diriez-vous des mnémoniques Intel 8080 vs Zilog Z80? Je suppose que cela est antérieur à la guerre de syntaxe Intel vs AT&T.
supercat
Sans discuter, je viens de mentionner cet aspect (syntaxe différente) et j'ai donné un exemple des deux syntaxes les plus populaires / bien connues / célèbres.
informatik01
4

Code source, code d'assemblage, code machine, code objet, code octet, fichier exécutable et fichier bibliothèque.

Tous ces termes sont souvent très déroutants pour la plupart des gens car ils pensent qu'ils s'excluent mutuellement . Voir le schéma pour comprendre leurs relations. La description de chaque terme est donnée ci-dessous.


Types de code


Code source

Instructions en langage lisible par l'homme (programmation)


Code de haut niveau

Instructions écrites dans un langage (de programmation) de haut niveau
, par exemple les programmes C, C ++ et Java


Code d'assemblage

Instructions écrites dans un langage d'assemblage (sorte de langage de programmation de bas niveau). Comme première étape du processus de compilation, le code de haut niveau est converti dans ce formulaire. C'est le code assembleur qui est ensuite converti en code machine réel. Sur la plupart des systèmes, ces deux étapes sont effectuées automatiquement dans le cadre du processus de compilation.
par exemple, program.asm


Code objet

Le produit d'un processus de compilation. Il peut prendre la forme d'un code machine ou d'un code octet.
par exemple, file.o


Langage machine

Instructions en langage machine.
par exemple, a.out


Code octet

Instruction sous une forme intermédiaire qui peut être exécutée par un interprète tel que JVM.
par exemple, fichier de classe Java


Fichier exécutable

Le produit de la liaison du processus. Ce sont des codes machine qui peuvent être directement exécutés par la CPU.
par exemple, un fichier .exe.

Notez que dans certains contextes, un fichier contenant du code d'octet ou des instructions de langage de script peut également être considéré comme exécutable.


Fichier de bibliothèque

Du code est compilé dans ce formulaire pour différentes raisons telles que la réutilisation et plus tard utilisé par les fichiers exécutables.

Bertram Gilfoyle
la source
1
Je dirais que tout assemblage n'est pas vraiment une source au sens strict du code écrit et / ou maintenu par les humains. Souvent, il est généré par la machine à partir de la source et n'est jamais destiné à la consommation humaine (par exemple, gcc crée vraiment du texte asm qu'il alimente dans un assembleur séparé, au lieu d'avoir un assembleur intégré à l'intérieur de l' cc1exécutable). Je pense que le cercle asm devrait dépasser du côté gauche du cercle "source", parce que certains asm sont juste asm, pas source. Ce n'est jamais du code objet , bien sûr, mais certains asm sont une étape sur le chemin entre les fichiers source et les fichiers objets.
Peter Cordes
@PeterCordes Merci beaucoup pour le commentaire. Je ne savais pas ce que vous avez dit sur le fonctionnement de gcc. Cependant, je crains que je ne sois entièrement d'accord avec vous. Ce que je veux dire, c'est que le code source est quelque chose d'écrit en utilisant un langage de programmation lisible par l'homme. Il peut ou non être écrit ou maintenu par des humains. Je suis sûr que vous serez au courant des transcompilateurs. De votre point de vue, dans quelle catégorie placerez-vous le produit d'un tel compilateur? Code source ou autre chose? Corrigez-moi si j'ai tort, s'il-vous plait. D'autres commentaires sont toujours les bienvenus.
Bertram Gilfoyle
1

Le code d'assemblage est discuté ici .

"Un langage d'assemblage est un langage de bas niveau pour la programmation d'ordinateurs. Il implémente une représentation symbolique des codes machine numériques et d'autres constantes nécessaires pour programmer une architecture CPU particulière."

Le code machine est discuté ici .

"Le code machine ou le langage machine est un système d'instructions et de données exécuté directement par l'unité centrale de traitement d'un ordinateur."

Fondamentalement, le code assembleur est le langage et il est traduit en code objet (le code natif que le CPU exécute) par un assembleur (analogue à un compilateur).

rbrayb
la source
1

Je pense que ce sont les principales différences

  • lisibilité du code
  • le contrôle de ce que fait votre code

La lisibilité peut rendre le code amélioré ou remplacé 6 mois après sa création avec un petit effort, d'autre part, si les performances sont critiques, vous pouvez utiliser un langage de bas niveau pour cibler le matériel spécifique que vous aurez en production, donc pour obtenir exécution plus rapide.

Aujourd'hui, les ordinateurs de l'OMI sont assez rapides pour permettre à un programmeur d'obtenir une exécution rapide avec la POO.

Alberto Zaccagni
la source
1

L'assemblage est un terme descriptif court que les humains peuvent comprendre et qui peut être directement traduit dans le code machine qu'un processeur utilise réellement.

Bien que quelque peu compréhensible par les humains, Assembler est toujours de bas niveau. Il faut beaucoup de code pour faire quelque chose d'utile.

Donc, à la place, nous utilisons des langages de niveau supérieur tels que C, BASIC, FORTAN (OK, je sais que je suis sorti avec moi-même). Une fois compilés, ils produisent du code objet. Les premiers langages avaient le langage machine comme code objet.

De nombreux langages aujourd'hui tels que JAVA et C # se compilent généralement en un bytecode qui n'est pas du code machine, mais qui peut être facilement interprété au moment de l'exécution pour produire du code machine.

Jim C
la source
Votre commentaire sur Java et C # - les deux utilisent la compilation Just In Time afin que les bytecodes ne soient pas interprétés. C # (.NET en général) se compile en langage intermédiaire (IL) qui est ensuite JIT en langage machine natif pour le CPU cible.
Craig Shearer
-1

Les fichiers source de vos programmes sont compilés en fichiers objets, puis l'éditeur de liens relie ces fichiers objets ensemble, produisant un fichier exécutable comprenant les codes machine de votre architecture.

Le fichier objet et le fichier exécutable impliquent le code machine de l'architecture sous la forme de caractères imprimables et non imprimables lorsqu'il est ouvert par un éditeur de texte.

Néanmoins, la dichotomie entre les fichiers est que le ou les fichiers objets peuvent contenir des références externes non résolues (comme printf, par exemple). Par conséquent, il peut être nécessaire de le lier à d'autres fichiers d'objets. C'est-à-dire que les références externes non résolues doivent être résolues afin d'obtenir le fichier exécutable exécutable décent en établissant une liaison avec d'autres fichiers objets tels que la bibliothèque d'exécution C / C ++. .

snr
la source