Une instruction en code machine amène le processeur à effectuer une tâche spécifique telle que :
- Charger un mot depuis la mémoire vers un registre du processeur
- Exécuter une opération d' unité arithmétique et logique (UAL) sur un ou plusieurs registres ou emplacements mémoire
- Passez directement à une instruction qui n'est pas la suivante .
L'architecture d' un jeu d'instructions (ISA) définit l'interface avec un processeur et varie selon les familles de processeurs, comme x86 et ARM . En général, le code machine compatible avec une famille ne l'est pas forcément avec une autre, mais il existe des exceptions. L' architecture VAX prend en charge, en option, le jeu d'instructions PDP-11 . L' architecture IA-64 prend en charge, en option, le jeu d'instructions IA-32 . Enfin, le PowerPC 615 peut traiter nativement les instructions PowerPC et x86.
Le langage assembleur permet une conversion relativement directe d'un code source lisible par l'humain vers du code machine. Le code source en assembleur représente les codes numériques en code machine, sous forme de mnémoniques et d'étiquettes. Par exemple, en assembleur pour un processeur x86 , l' opcode 0x90 de l'architecture x86 est représenté en code machine. Bien qu'il soit possible d'écrire un programme en code machine, cette opération est fastidieuse et sujette aux erreurs. C'est pourquoi les programmes sont généralement écrits en assembleur ou, plus couramment, dans un langage de programmation de haut niveau .NOP
Jeu d'instructions
Une instruction machine encode une opération sous forme d'un motif de bits basé sur le format spécifié pour le jeu d'instructions de la machine.
Les jeux d'instructions diffèrent de plusieurs manières. Les instructions d'un même jeu peuvent avoir toutes la même longueur ou des instructions différentes peuvent avoir des longueurs différentes ; elles peuvent être plus petites, de même taille ou plus grandes que la taille des mots de l'architecture. Le nombre d'instructions peut être relativement faible ou élevé. Les instructions peuvent être alignées ou non sur des limites de mémoire particulières, telles que la limite de mot de l'architecture.
Un jeu d'instructions est nécessaire pour exécuter les circuits de la couche logique numérique d'un ordinateur . À ce niveau, le programme doit contrôler les registres, le bus, la mémoire, l'unité arithmétique et logique (UAL) et les autres composants matériels de l'ordinateur. Pour contrôler les caractéristiques architecturales d'un ordinateur , des instructions machine sont créées. Exemples de caractéristiques contrôlées par des instructions machine :
Les critères relatifs aux formats d'enseignement comprennent :
- Les instructions les plus fréquemment utilisées devraient être plus courtes que les instructions rarement utilisées.
- Le débit de transfert de mémoire du matériel sous-jacent détermine la flexibilité des instructions d'accès à la mémoire.
- Le nombre de bits dans le champ d'adresse nécessite une attention particulière.
Le choix de la taille du champ d'adresse implique un compromis entre espace mémoire et vitesse. Sur certains ordinateurs, le nombre de bits du champ d'adresse peut être insuffisant pour accéder à l'intégralité de la mémoire physique. Il convient également de tenir compte de l'espace d'adressage virtuel . Une autre contrainte peut être la limitation de la taille des registres utilisés pour construire l'adresse. Si un champ d'adresse plus court permet une exécution plus rapide des instructions, d'autres propriétés physiques doivent être prises en compte lors de la conception du format d'instruction.
Les instructions peuvent être classées en deux catégories : les instructions à usage général et les instructions à usage spécifique. Les instructions à usage spécifique exploitent des caractéristiques architecturales propres à un ordinateur. Les instructions à usage général contrôlent des caractéristiques architecturales communes à tous les ordinateurs.
Contrôle des instructions à usage général :
- déplacement de données d'un endroit à un autre
- Opérations monadiques qui ont un seul opérande pour produire un résultat
- Opérations dyadiques qui ont deux opérandes pour produire un résultat
- Comparaisons et sauts conditionnels
- Appels de procédure
- Contrôle de boucle
- Entrée/sortie
Instructions superposées
Sur les architectures de processeurs à jeu d'instructions de longueur variable (comme la famille de processeurs x86 d' Intel ), il est parfois possible, dans les limites du phénomène de resynchronisation du flux de contrôle connu sous le nom de comptage de Kruskal , , par programmation au niveau des opcodes, d'organiser délibérément le code résultant de sorte que deux chemins d'exécution partagent un fragment commun de séquences d'opcodes. On parle alors d'instructions chevauchantes , d'opcodes chevauchants , de code chevauché , de scission d'instruction ou de saut au milieu d'une instruction .
Dans les années 1970 et 1980, le chevauchement des instructions était parfois utilisé pour économiser de l'espace mémoire. On peut citer en exemple l'implémentation des tables d'erreurs dans Altair BASIC de Microsoft , où les instructions entrelacées partageaient leurs octets. Cette technique est rarement employée aujourd'hui, mais peut encore s'avérer nécessaire dans des domaines exigeant une optimisation extrême de la taille au niveau de l'octet, comme lors de l'implémentation des chargeurs d'amorçage qui doivent tenir dans les secteurs d'amorçage .
Elle est parfois utilisée comme technique d'obfuscation de code afin de se prémunir contre le désassemblage et la falsification.
Ce principe est également utilisé dans les séquences de code partagées des binaires volumineux qui doivent s'exécuter sur plusieurs plateformes de processeurs incompatibles en termes de jeu d'instructions.
Cette propriété est également utilisée pour trouver des instructions non intentionnelles appelées gadgets dans les dépôts de code existants et est utilisée dans la programmation orientée retour comme alternative à l'injection de code pour des exploits tels que les attaques de retour à la libc .
Microcode
Sur certains ordinateurs, le code machine de l' architecture est implémenté par une couche sous-jacente encore plus fondamentale appelée microcode , fournissant une interface en langage machine commune à une gamme ou une famille de modèles d'ordinateurs différents, présentant des flux de données sous-jacents très différents . Ceci facilite la portabilité des programmes en langage machine entre différents modèles. La famille d'ordinateurs IBM System/360 et ses successeurs en sont un exemple .
Exemples
IBM 650


L' IBM 650 , commercialisé en 1954, était un ordinateur décimal à adressage par mot, dont les instructions et les données étaient stockées sur un tambour magnétique. Chaque mot était composé de dix chiffres suivis du signe plus. Les instructions divisaient les mots en un code d'opération à deux chiffres, une adresse à quatre chiffres du mot de données à traiter et une adresse à quatre chiffres de l'instruction suivante à exécuter. Cette seconde adresse permettait de placer les instructions sur le tambour à proximité de sa position après l'exécution de l'instruction précédente, une pratique appelée optimisation.
Grâce à une table physique de codes d'opération, il était tout à fait possible d'écrire des programmes en code machine. IBM fournissait un formulaire comportant une grille indiquant chaque emplacement mémoire, permettant ainsi au programmeur de suivre les emplacements disponibles. Un format d'instruction unique par carte permettait de charger et d'exécuter directement le programme dans la machine. Plus tard, IBM a introduit un assembleur (SOAP) qui autorisait l'adressage symbolique et effectuait également une première optimisation.
IBM 709x
Les IBM 704, 709, 704x et 709x stockent une instruction dans chaque mot d'instruction ; IBM numérote les bits de gauche à droite comme suit : S, 1, ..., 35. La plupart des instructions ont l'un des deux formats suivants :
- Générique
- S,1-11
- Drapeau 12-13, ignoré dans certaines instructions
- 14-17 non utilisés
- Étiquette 18-20
- 21-35 ans
- Contrôle des registres d'index, autre que TSX
- Code d'opération S,1-2
- Décrémentation 3-17
- Étiquette 18-20
- 21-35 ans
Pour tous les automates, à l'exception des IBM 7094 et 7094 II, il existe trois registres d'index, désignés A, B et C. L'indexation avec plusieurs bits à 1 dans l'étiquette soustrait le résultat du OU logique des registres d'index sélectionnés, et le chargement avec plusieurs bits à 1 dans l'étiquette charge tous les registres d'index sélectionnés. Les 7094 et 7094 II possèdent sept registres d'index, mais à leur mise sous tension, ils fonctionnent en mode multi-étiquettes . Dans ce mode, ils n'utilisent que trois des registres d'index, de manière compatible avec les machines plus anciennes, et nécessitent une instruction de sortie du mode multi-étiquettes ( LMTM ) pour accéder aux quatre autres.
L'adresse effective est généralement YC(T), où C(T) vaut soit 0 pour une étiquette de 0, soit le OU logique des registres d'index sélectionnés en mode d'étiquettes multiples, soit le registre d'index sélectionné si ce mode n'est pas utilisé. Cependant, l'adresse effective pour les instructions de contrôle des registres d'index est simplement Y.
Un indicateur avec les deux bits à 1 sélectionne l'adressage indirect ; le mot d'adresse indirecte possède à la fois une étiquette et un champ Y.
En plus des instructions de transfert (branchement), ces machines disposent d'instructions de saut qui permettent de sauter conditionnellement un ou deux mots, par exemple, Compare Accumulator with Storage (CAS) effectue une comparaison à trois voies et saute conditionnellement à NSI, NSI+1 ou NSI+2, en fonction du résultat.
MIPS
L' architecture MIPS fournit un exemple précis de code machine dont les instructions sont toujours codées sur 32 bits. Le type général d'instruction est indiqué par le champ op (opération), dont les 6 bits de poids fort sont utilisés. Les instructions de type J (saut) et de type I (immédiat) sont entièrement spécifiées par op . Les instructions de type R (registre) incluent un champ funct (fonction) supplémentaire pour déterminer l'opération exacte. Les champs utilisés pour ces types sont :
| Taper | -31- format (bits) -0- | |||||
|---|---|---|---|---|---|---|
| R | code d'opération (6) | rs (5) | rt (5) | rd (5) | shamt (5) | fonction (6) |
| je | code d'opération (6) | rs (5) | rt (5) | immédiat (16) | ||
| J | code d'opération (6) | adresse (26) | ||||
rs , rt et rd indiquent des opérandes de registre ; shamt indique un décalage ; et les champs d’adresse ou immédiats contiennent directement un opérande.
Par exemple, l'addition des registres 1 et 2 et le placement du résultat dans le registre 6 sont codés comme suit :
[ op | rs | rt | rd |shamt| funct] 0 1 2 6 0 32 décimal 000000 00001 00010 00110 00000 100000 binaire
Charger une valeur dans le registre 8, extraite de la cellule mémoire située 68 cellules après l'adresse indiquée dans le registre 3 :
[ op | rs | rt | adresse/immédiat] 35 3 8 68 décimal 100011 00011 01000 00000 00001 000100 binaire
Accès à l'adresse 1024 :
[ op | adresse cible ] 2 1024 décimal 000010 00000 00000 00000 10000 000000 binaire
Bytecode
Le code machine est similaire au bytecode , mais fondamentalement différent . Comme le code machine, le bytecode est généralement généré (par exemple par un compilateur) à partir du code source. Cependant, contrairement au code machine, le bytecode n'est pas directement exécutable par un processeur. Une exception existe pour les processeurs conçus pour utiliser le bytecode comme code machine, tels que le MicroEngine Pascal ou un processeur Java . Si le bytecode est traité par un interpréteur logiciel, cet interpréteur constitue alors une machine virtuelle dont le bytecode représente le code machine.
Stockage
Lors de l'exécution, le code machine est généralement stocké dans la RAM, bien que certains appareils prennent en charge l'exécution depuis la ROM. Quoi qu'il en soit, le code peut également être mis en cache dans une mémoire plus spécialisée afin d'améliorer les performances. Il peut exister différents caches pour les instructions et les données, selon l'architecture.
Du point de vue d'un processus , le code machine réside dans l'espace de code , une partie désignée de son espace d'adressage . Dans un environnement multithread , différents threads d'un même processus partagent l'espace de code ainsi que l'espace de données, ce qui réduit considérablement la surcharge liée au changement de contexte par rapport au changement de processus.
Lisibilité
Le code machine est généralement considéré comme illisible par l'homme , Douglas Hofstadter le comparant à l'examen des atomes d'une molécule d'ADN . Cependant, divers outils et méthodes permettent de comprendre le code machine.
Le désassemblage décode le code machine en langage assembleur, ce qui est possible puisque les instructions assembleur peuvent souvent être mappées une à une aux instructions machine.
Un décompilateur convertit le code machine en un langage de haut niveau , mais le résultat peut être relativement obscurci (difficile à comprendre).
Un programme peut être associé à des symboles de débogage (intégrés à l' exécutable natif ou dans un fichier séparé) permettant de l'associer à du code source externe. Un débogueur lit ces symboles pour aider le programmeur à déboguer le programme de manière interactive. Exemples :
- Le système d'exploitation SHARE (1959) pour les ordinateurs IBM 709 , IBM 7090 et IBM 7094 permettait le chargement d'un format de code nommé SQUAZE . SQUAZE était une forme binaire compressée de code en langage assembleur et incluait une table des symboles.
- Les systèmes d'exploitation modernes pour mainframe IBM , tels que z/OS , disposent d'une table de symboles nommée Associated data (ADATA). Cette table est stockée dans un fichier pouvant être généré par l' assembleur de haut niveau IBM (HLASM) , le compilateur COBOL d'IBM et le compilateur PL/I d'IBM , soit sous forme de fichier SYSADATA distinct, soit sous forme d'enregistrements ADATA dans un fichier de sortie d'objet généralisé (GOFF) . Ceci rend obsolètes les enregistrements TEST d' OS/360 , bien qu'il soit toujours possible de les demander et de les utiliser dans la commande TSO TEST.
- Windows utilise une table de symboles qui est stockée dans un fichier de base de données de programme ( .pdb ).
- La plupart des systèmes d'exploitation de type Unix proposent des formats de table de symboles appelés stabs et DWARF . Sous macOS et autres systèmes d'exploitation basés sur Darwin , les symboles de débogage sont stockés au format DWARF dans un fichier .dSYM distinct.
Plus d articles de Worldlex Wiki
Revenez a l index pour explorer davantage de pages sur l histoire, la science, la culture, la geographie et la societe en francais.
Explorer l index