Un langage d'assemblage universel pour tous les ordinateurs est-il possible?

23

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.

nTuply
la source
10
Quelles recherches avez-vous faites? Nous attendons de vous que vous fassiez des recherches avant de demander, pour vous aider à poser une meilleure question. Il y a beaucoup écrit sur le langage d'assemblage.
DW
4
Nous nous attendons à ce que vous fassiez une quantité importante de recherche / d'auto-étude avant de demander, et de nous dire dans la question quelles recherches vous avez faites. Dans ce cas, la recherche pourrait inclure la lecture d'articles pertinents de Wikipédia (par exemple, sur le langage d'assemblage et l'architecture informatique) et la lecture d'un manuel d'architecture informatique. Pour en faire une meilleure question: faites cette recherche, si vous ne l'avez pas déjà fait, puis modifiez la question pour expliquer la recherche que vous avez effectuée. Ce type de recherche vous aide souvent à formuler une meilleure question; et en tout cas cela aide les répondeurs à éviter de répéter ce que vous savez déjà.
DW
15
Commencez par comprendre que / pourquoi il n'y a pas de langage appelé Assemblée.
Raphael
2
un problème "classique" avec la portabilité C est différentes tailles de primitives (par exemple des nombres entiers) sur différents matériels et il y en a d'autres cités.
vzn
3
Il s'agit plus d'un problème social que d'un problème technique - vous devez convaincre tous les fabricants de CPU de faire en sorte que leurs CPU acceptent le même langage machine. (En fait, x86 allait presque être ça, par hasard - puis les smartphones ont décollé)
user253751

Réponses:

45

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.

DW
la source
1
Je pense que cette question est déjà répondu par le 3ème paragraphe de ma réponse. Comme vous l'avez dit, un tel schéma ne serait pas efficace, il serait donc fondamentalement contraire à la raison principale d'utiliser le langage d'assemblage.
DW
26
@nTuply Dès que vous modifiez votre langage d'assemblage pour répondre à différentes machines, il est devenu un langage de haut niveau avec une syntaxe de style assembleur horrible. Une fois que vous avez décidé d'utiliser un langage de haut niveau, vous pouvez aussi bien en utiliser un avec une syntaxe plus conviviale et laisser le compilateur faire le travail.
David Richerby
15
Ce n'est pas une idée complètement stupide d'avoir un "langage d'assemblage" qui est traduit pour différentes machines, parce que c'est essentiellement ce qu'est le "IR" de LLVM. Cependant, pour les raisons David donne, vous ne normalement écrire assemblage LLVM. De plus, parce que 99 fois sur 100, vous feriez un pire travail d'écriture que de traduire votre C en LLVM. Les langages d'assemblage sont potentiellement plus efficaces que les langages de haut niveau, mais entre les mains de la plupart des programmeurs actuels avec un temps typique disponible pour l'optimisation, ils n'atteignent pas leur potentiel de toute façon.
Steve Jessop
9
@nTuply, cela existe. Le processus de passage de ce langage extra-assembleur aux instructions machine est appelé compilation.
Paul Draper
3
@PJTraill Il n'y a aucune raison d'écrire un compilateur en assembleur sur un système moderne, à l'exception de la toute première étape d'amorçage (et la plupart du temps, pas même alors). Les compilateurs écrits dans un langage de haut niveau sont beaucoup plus susceptibles d'être réellement maintenables. Comparez également Comment un langage dont le compilateur est écrit en C peut-il être plus rapide que C? . Le but d'un compilateur est de traduire d'une langue (la langue source) à une autre (généralement un langage machine pour une architecture et un système d'exploitation spécifiques); cela peut être écrit dans n'importe quelle langue.
un CVn le
13

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.

Geai
la source
1
C a souvent été décrit comme «langage d'assemblage portable».
Larry Gritz,
2
@LarryGritz Bien sûr. Et lorsque C a été inventé, il était révolutionnaire: il offrait une grande partie de la puissance du langage d'assemblage avec la facilité d'utilisation d'un compilé. Mais par définition, c'est toujours un langage compilé
Jay
8

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.

Raphael
la source
6
"si on peut en croire un minuscule" - il y a vos deux types de programmeurs là. Ceux qui considèrent C comme un langage de bas niveau parce que ses opérations de base ressemblent beaucoup au genre de choses qui apparaissent dans les jeux d'instructions du processeur, et ceux qui considèrent C comme un langage de haut niveau parce que ce n'est pas la même chose jeu d'instructions que la machine.
Steve Jessop
Si, par langage d'assemblage, vous entendez un contrôle total sur le code machine généré pour un type (ou une famille) de matériel spécifique, il serait possible de définir un langage «pour tous les ordinateurs» dans notre monde à un moment donné, mais ce serait doivent continuer à changer. Il serait certes (si bien conçu) de raccourcir la courbe d'apprentissage pour le codage d'une nouvelle architecture, mais je m'attends à ce que tout travail que vous souhaitiez faire avec lui plutôt qu'un compilateur ne s'applique qu'à une infime fraction des architectures. Que les ordinateurs soient les mêmes à un niveau abstrait est un hareng rouge, il s'agit de code machine.
PJTraill
7

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.

vzn
la source
8
Sun n'a pas inventé de machines virtuelles ou de code d'octets, ils n'étaient même pas le premier groupe à en tirer de l'argent. Recherchez le code p.
jmoreno
@jmoreno: il pourrait également vouloir rechercher Smalltalk.
Bob Jarvis - Reinstate Monica
l'article ne prétend pas que les machines virtuelles / code d'octet ont été inventés par Sun. il y a une autre histoire non citée mais évoquée. btw une autre technologie clé très pertinente ici: google native client (fonctionnalité chrome)
vzn
5

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:

  • Calcul (arithmétique et logique)
  • Flux de contrôle
  • Transfert de données
  • Configuration du processeur

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.

Artelius
la source
Excellente réponse! Les gens ne comprennent pas assez bien que les choses informatiques qui doivent être programmées sont partout parmi nous. Ce ne sont pas seulement les applications que nous voyons fonctionner sur nos écrans. Combien de milliards de puces sont fabriquées chaque année?
phs
4

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.

Mal
la source
Dans la grande majorité des cas, gcc effectue une meilleure optimisation qu'un programmeur. Le point principal de l'utilisation de l'assembleur est de faire des choses que vous ne pouvez pas faire en C comme accéder aux registres. Si vous regardez l'arborescence des sources Linux, c'est à peu près pour cela qu'ils utilisent l'assemblage.
slebetman
@slebetman - gcc vous permet de mettre une variable dans un registre sans avoir recours à l'assembly.
Jirka Hanika
@JirkaHanika: parlez-vous de registres de CPU ou de registres matériels à usage spécifique adressés avec des instructions spéciales? Je soupçonne que Slebetman signifie ce dernier.
PJTraill du
"Tous les codes" - "GCC fait mieux" = "vous utilisez l'assembleur". Oui, vous pouvez accéder aux registres sans insertions d'assembleur.
Evil
@PJTraill - Le commentaire de Slebetman est généralement excellent et devrait peut-être être incorporé dans la réponse. Mais, ses deux exemples (accès aux registres et arborescence des sources Linux) sont susceptibles de nourrir des idées fausses courantes plutôt que d'être d'excellents exemples de ce que l' on ne peut pas faire en C avec des extensions gcc; ceux-ci devraient être remplacés ou omis. (S'il y a une instruction HW pour faire quelque chose aujourd'hui, vous aurez l'extension gcc correspondante dans un an. Pas toujours, mais très souvent. Les exemples vieillissent.)
Jirka Hanika
3

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.

Russell Harkins
la source
Quelle est la différence entre "langage d'assemblage intermédiaire" et "machine virtuelle"?
Bob Jarvis - Reinstate Monica
@BobJarvis: L'un est du code tandis que l'autre est un interprète. Vous auriez dû demander quelle est la différence entre l'assemblage intermédiaire et le bytecode
slebetman
Cela ne semble pas répondre à la question. Tant que chaque machine compile / assemble MSIL différemment, elle n'a rien d'universel, et le but d'une telle compilation est le portage de fonctionnalités génériques, et non l'exploitation d'un jeu d'instructions particulier, qui, comme le souligne DW, est le (ou a) raison d'utiliser l'assembleur.
PJTraill du
3

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).

Rob
la source
0

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.

Chris
la source
La question porte sur un langage d'assemblage qui peut être utilisé pour programmer n'importe quel ordinateur, et non sur un langage d'assemblage universel au sens de "machine de Turing universelle".
David Richerby
1
Church-Turing nous dit que l'UTC peut faire ce que n'importe quel ordinateur programmable peut faire. Mis à part les problèmes de stockage physique fini. Un langage d'assemblage pour un UTC est tout à fait réalisable. Mais comme je l'ai dit, l'aspect pratique culturel et économique peut limiter la mise en œuvre et l'adoption réelles sur le marché.
Chris
Vous manquez le plus gros problème, qui est la performance ! Pourquoi utiliser un langage des milliers de fois plus lentement juste pour un objectif noble d'être indépendant du matériel? La machine de Turing est un terrible modèle pour l'informatique pratique.
Artelius
1
Les commentateurs voudraient-ils proposer une quelconque informatique pour appuyer leurs revendications? C'est après tout le forum informatique.
Chris
1
Je ne suis pas un expert CS. Mais ce que je crois, c'est que l'architecture de von Neumann est une brillante ingénierie qui établit un équilibre entre la programmabilité et les performances, tandis que le but de la machine Turing est de montrer que même la machine la plus élémentaire peut calculer tout ce qu'une machine plus complexe pourrait. Bien sûr, vous pouvez continuer à ajouter de plus en plus de fonctionnalités à une machine de Turing (plus de bandes, d'arithmétique), mais vous obtenez alors le même problème que vous aviez en premier lieu, à savoir des personnes qui ne s'entendent pas sur un ensemble d'instructions. De plus, le manque d'accès aléatoire crée de gros frais généraux dans de nombreux algorithmes.
Artelius
0

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

Taoufik Dachraoui
la source
Vous ne savez donc pas si votre réponse est vraie? Et ne peut pas le supporter?
Evil