Je voudrais poser quelques questions sur le langage de l'Assemblée. Ma compréhension est qu'il est très proche du langage machine, ce qui le rend plus rapide et plus efficace.
Étant donné que différentes architectures informatiques existent, cela signifie-t-il que je dois écrire du code différent dans Assembly pour différentes architectures? Si c'est le cas, pourquoi Assembly n'est-il pas, écrivez une fois - exécutez partout le type de langage? Ne serait-il pas plus facile de simplement le rendre universel, de sorte que vous ne puissiez l'écrire qu'une seule fois et l'exécuter sur pratiquement n'importe quelle machine avec différentes configurations? (Je pense que ce serait impossible, mais j'aimerais avoir des réponses concrètes et approfondies)
Certaines personnes pourraient dire que C est le langage que je recherche. Je n'ai pas utilisé C auparavant mais je pense que c'est toujours un langage de haut niveau, bien que probablement plus rapide que Java, par exemple. Je me trompe peut-être ici.
Réponses:
Le langage d'assemblage est un moyen d'écrire des instructions pour le jeu d' instructions de l'ordinateur , d'une manière qui est légèrement plus compréhensible pour les programmeurs humains.
Différentes architectures ont des jeux d'instructions différents: le jeu d'instructions autorisées est différent sur chaque architecture. Par conséquent, vous ne pouvez pas espérer avoir un programme d'assemblage en écriture une fois exécuté partout. Par exemple, l'ensemble d'instructions prises en charge par les processeurs x86 est très différent de l'ensemble d'instructions prises en charge par les processeurs ARM. Si vous avez écrit un programme d'assemblage pour un processeur x86, il contiendrait de nombreuses instructions qui ne sont pas prises en charge sur le processeur ARM, et vice versa.
La principale raison d'utiliser le langage d'assemblage est qu'il permet un contrôle de très bas niveau sur votre programme, et de tirer parti de toutes les instructions du processeur: en personnalisant le programme pour profiter des fonctionnalités qui sont uniques au processeur particulier qu'il fonctionnera, vous pouvez parfois accélérer le programme. La philosophie de l'écriture unique une fois partout est fondamentalement en contradiction avec cela.
la source
La DÉFINITION du langage d'assemblage est qu'il s'agit d'un langage qui peut être traduit directement en code machine. Chaque code d'opération en langage assembleur se traduit par exactement une opération sur l'ordinateur cible. (Eh bien, c'est un peu plus compliqué que cela: certains assembleurs déterminent automatiquement un "mode d'adressage" en fonction des arguments d'un code op. Mais le principe est qu'une ligne d'assemblage se traduit par une instruction en langage machine.)
Vous pourriez, sans aucun doute, inventer un langage qui ressemblerait à un langage d'assemblage mais qui serait traduit en différents codes machine sur différents ordinateurs. Mais par définition, ce ne serait pas un langage d'assemblage. Ce serait un langage de niveau supérieur qui ressemble au langage d'assemblage.
Votre question est un peu comme demander: "Est-il possible de faire un bateau qui ne flotte pas ou qui n'a pas d'autre moyen de traverser l'eau, mais qui a des roues et un moteur et qui peut voyager sur terre?" La réponse serait que, par définition, un tel véhicule ne serait pas un bateau. Cela ressemble plus à une voiture.
la source
Il n'y a pas conceptuelle (j'ose dire, pas d' ordinateur la science ) la raison contre avoir un langage d'assemblage pour tous les ordinateurs du monde. En fait, cela faciliterait beaucoup de choses. En ce qui concerne la théorie, ils sont tous les mêmes, de toute façon, jusqu'à une bijection funky.
Dans la pratique, cependant, il existe différentes puces à des fins différentes, avec des opérations et des principes de conception différents (par exemple, RISC vs CISC) qui servent des objectifs différents, et les jeux d'instructions qui les exploitent et, par conséquent, les langages d'assemblage diffèrent. En fin de compte, la réponse est la même que lorsque vous demandez pourquoi il existe autant de langages de programmation différents: des objectifs différents, des décisions de conception différentes.
Cela dit, vous pouvez bien sûr introduire des niveaux d'abstraction pour accéder à une interface partagée. x86, par exemple, a été supprimé au niveau de la puce depuis un certain temps; il y a un petit matériel qui traduit les instructions x86 en ce que votre processeur fonctionne vraiment . Des langages comme C seraient une autre étape loin du matériel (s'il est sans doute minuscule), jusqu'à des langages comme Haskell, Java ou Ruby. Oui, le compilateur est l'une des principales réalisations de l'informatique car il permet de séparer les préoccupations de cette manière.
la source
Vous mentionnez l'expression «écrire une fois n'importe où» sans avoir l'air de remarquer sa signification. Tel est le slogan marketing de Sun Microsystems qui a inventé commercialement le concept de "machine virtuelle" et de "bytecodes" pour Java, bien que l'idée puisse provenir du monde universitaire 1 er. L'idée a ensuite été copiée par Microsoft pour .Net après avoir été poursuivie avec succès par Sun pour violation de la licence Java. Les bytecodes Java sont une implémentation de l'idée d'assemblage multi-machine ou de langage machine. Ils sont utilisés pour plusieurs autres langages que Java et peuvent théoriquement être utilisés pour compiler n'importe quel langage. Après de nombreuses années d'optimisation très avancée, Java se rapproche des performances des langages compilés, ce qui montre que l'objectif d'une technologie de machine virtuelle indépendante de la plate-forme haute performance est réalisable en général.
Une autre nouvelle idée dans les premiers stades / circulant liée à vos besoins s'appelle le projet de recalcul et est pour la recherche scientifique bien qu'elle puisse être utilisée à d'autres fins. L'idée est de rendre les expériences de calcul reproductibles via la technologie des machines virtuelles. C'est principalement l'idée de simuler différentes architectures de machines sur du matériel arbitraire.
la source
Raisons de haut niveau
Quand on y pense, un microprocesseur fait une chose étonnante: il vous permet de prendre une machine (comme une machine à laver ou un ascenseur), et de remplacer un morceau entier de sur mesure des mécanismes ou des circuits avec un pas cher, produit en masse silicium puce. Vous économisez beaucoup d'argent sur les pièces et beaucoup de temps sur la conception.
Mais attendez, une puce standard , remplaçant d'innombrables personnalisées designs ? Il ne peut pas y avoir un seul microprocesseur parfait qui soit parfait pour chaque application. Certaines applications doivent réduire la consommation d'énergie mais n'ont pas besoin d'être rapides; d'autres doivent être rapides mais ne doivent pas être faciles à programmer, d'autres doivent être peu coûteux, etc.
Nous avons donc de nombreuses «saveurs» différentes de microprocesseur, chacune avec ses propres forces et faiblesses. Il est souhaitable qu'ils utilisent tous un jeu d'instructions compatible, car cela permet la réutilisation du code et facilite la recherche de personnes possédant les bonnes compétences. Cependant, le jeu d'instructions ne n'influent sur le coût, la complexité, la rapidité, la facilité d'utilisation et des contraintes physiques du processeur, et nous avons donc un compromis: il quelques jeux d'instructions « mainstream » (et beaucoup de ceux mineurs), et dans chaque jeu d'instructions, il existe de nombreux processeurs avec des caractéristiques différentes.
Oh, et à mesure que la technologie change, tous ces compromis changent, donc les ensembles d'instructions évoluent, de nouveaux émergent et les anciens meurent. Même s'il y avait un «meilleur» ensemble d'instructions d'aujourd'hui, ce ne serait peut-être pas dans 20 ans.
Détails du matériel
La plus grande décision de conception dans un jeu d'instructions est probablement la taille des mots , c'est-à-dire le nombre que le processeur peut manipuler "naturellement". Les processeurs 8 bits traitent les nombres de 0 à 255, tandis que les processeurs 32 bits traitent les nombres de 0 à 4 294 967 295. Le code conçu pour l'un doit être complètement repensé pour l'autre.
Il ne s'agit pas seulement de traduire des instructions d'un ensemble d'instructions à un autre. Une approche complètement différente peut être préférable dans un ensemble d'instructions différent. Par exemple, sur un processeur 8 bits, une table de recherche peut être idéale, tandis que sur un processeur 32 bits, une opération arithmétique serait préférable dans le même but.
Il existe d'autres différences majeures entre les jeux d'instructions. La plupart des instructions se répartissent en quatre catégories:
Les processeurs diffèrent dans le type de calculs qu'ils peuvent effectuer, ainsi que dans leur approche du flux de contrôle, du transfert de données et de la configuration du processeur.
Par exemple, certains processeurs AVR ne peuvent ni se multiplier ni se diviser; alors que tous les processeurs x86 le peuvent. Comme vous pouvez l'imaginer, l'élimination des circuits requis pour des tâches comme la multiplication et la division peut rendre un processeur plus simple et moins cher; ces opérations peuvent toujours être effectuées à l'aide de routines logicielles si elles sont nécessaires.
x86 permet aux instructions arithmétiques de charger leurs opérandes de la mémoire et / ou de sauvegarder leurs résultats en mémoire; ARM est une architecture de magasin de charge et n'a donc que quelques instructions dédiées pour accéder à la mémoire. Pendant ce temps, x86 a des instructions de branchement conditionnel dédiées, tandis que ARM permet à pratiquement toutes les instructions d'être exécutées sous condition. En outre, ARM permet d'effectuer des décalages de bits dans le cadre de la plupart des instructions arithmétiques. Ces différences entraînent des caractéristiques de performances différentes, des différences dans la conception interne et le coût des puces, et des différences dans les techniques de programmation au niveau du langage d'assemblage.
Conclusion
La raison pour laquelle il est impossible d'avoir un langage d'assemblage universel est que, pour convertir correctement le code d'assemblage d'un jeu d'instructions à un autre, il faut reconcevoir le code, ce que les ordinateurs ne peuvent pas encore faire.
la source
Ajout à la merveilleuse réponse de DW: si vous souhaitez avoir un assembleur, il devra maintenir toutes les architectures, un traducteur parfait entre elles et comprendre pleinement ce que vous faites.
Certains codes fortement optimisés pour une architecture devraient être désoptimisés, compris à un niveau plus abstrait et optimisés pour une autre.
Mais si cela était possible, nous aurions un compilateur C parfait, et l'écriture en assemblage pur ne serait pas du tout bénéfique.
Le point principal de l'utilisation de l'assembleur est la performance, qui ne peut pas être supprimée des compilateurs récents.
Écrire un tel programme serait encore plus difficile que les compilateurs existants et maintenir toutes les nouvelles architectures en cours de création le rendrait encore plus difficile.
Et pour «un seul» programme, cela signifierait également une compatibilité descendante complète.
la source
Microsoft a inventé MSIL pour être un langage d'assemblage intermédiaire. Les programmes compileraient de C # ou VB.Net vers MSIL. Au moment de l'exécution, le MSIL a été compilé en code machine pour la machine qui l'exécutait à l'aide d'un compilateur JIT . Le fichier contenant le MSIL était un fichier .exe avec quelques instructions au début dans X86 pour démarrer le programme. Sur un processeur ARM, vous devez taper le mot mono devant le nom du programme pour l'exécuter.
la source
Comme indiqué, LLVM est la chose la plus proche à ce jour. Une grande barrière à un langage vraiment universel sera les différences fondamentales liées aux compromis implicites: concurrence, utilisation de la mémoire, débit, latence et consommation d'énergie. Si vous écrivez dans un style explicitement SIMD, vous utilisez peut-être trop de mémoire. Si vous écrivez dans un style explicitement SISD, vous obtiendrez une parallélisation sous-optimale. Si vous optimisez le débit, vous réduisez la latence. Si vous maximisez le débit d'un seul thread (par exemple: la vitesse d'horloge), vous endommagez la durée de vie de la batterie.
À tout le moins, le code devrait être annoté avec les compromis. Ce qui peut être le plus important, c'est que le langage ait de bonnes propriétés algébriques / type qui donnent au compilateur beaucoup de marge de manœuvre pour optimiser et détecter les incohérences logiques.
Il y a ensuite la question du comportement indéfini. Une grande partie de la vitesse du langage C et des langages d'assemblage provient d'un comportement non défini. Si vous admettez un comportement indéfini qui se produit réellement, vous finissez par les traiter comme des cas spéciaux (c'est-à-dire: hacks spécifiques à l'architecture et au contexte).
la source
Peut-être que ce que vous recherchez est une notation Universal Turning Machine où tout le monde est d'accord sur les symboles des commandes. ( https://en.wikipedia.org/wiki/Universal_Turing_machine )
Un «assembleur» qui traduit un langage Turning Acceptable en code machine spécifique au fournisseur sous-jacent et qui est conçu pour toutes ces choses que nous appelons des ordinateurs.
Dans The Art of Computer Programming, il y a un exemple de ce à quoi cela pourrait ressembler.
Mais réfléchissez à la question «pourquoi n'est-ce pas un langage universel disponible dans le commerce qui peut être utilisé avec tous les ordinateurs? (2) l'économie, la fourniture, l'incompatibilité entre les machines de différentes marques et les fournisseurs est une stratégie commerciale ainsi que le résultat de ressources limitées (temps / argent) pour concevoir des machines.
la source
hypothèse: la compilation et l'optimisation d'un langage de haut niveau L1 vers un langage de niveau inférieur L0 est plus facile que la compilation et l'optimisation d'un langage de haut niveau L2 (supérieur à L1) à L0; plus facile dans le sens où vous pouvez générer un code plus optimisé lors de la compilation de L1 à L0 que de L2 à L0.
Je pense que l'hypothèse est probablement correcte, c'est pourquoi probablement la plupart des compilateurs utilisent un langage intermédiaire de bas niveau (IR / LLVM).
si cela est vrai, utilisez un langage de bas niveau L0 et écrivez des compilateurs pour traduire L0 dans d'autres langages de bas niveau. Par exemple, utilisez le jeu d'instructions MIPS et compilez-le en x86, arm, power, ...
-Taoufik
la source