Pourquoi les programmes ne sont-ils pas écrits plus souvent dans Assembly? [fermé]


216

Il semble être une opinion répandue que la programmation d'assemblage prend plus de temps et est plus difficile à programmer dans un langage de niveau supérieur tel que C. Par conséquent, il semble être recommandé ou supposé qu'il est préférable d'écrire dans un langage de niveau supérieur pour ces raisons et pour une meilleure portabilité.

Récemment, j'ai écrit dans un assemblage x86 et il m'est apparu que peut-être ces raisons ne sont pas vraiment vraies, sauf peut-être la portabilité. C'est peut-être plus une question de familiarité et de savoir bien écrire l'assemblage. J'ai également remarqué que la programmation en assembleur est assez différente de la programmation en HLL. Peut-être qu'un bon programmeur assembleur expérimenté pourrait écrire des programmes aussi facilement et aussi rapidement qu'un programmeur C expérimenté écrivant en C.

C'est peut-être parce que la programmation d'assemblage est assez différente de celle des HLL, et nécessite donc une réflexion, des méthodes et des manières différentes, ce qui rend très difficile la programmation pour les inconnus, et lui donne donc son mauvais nom pour l'écriture de programmes.

Si la portabilité n'est pas un problème, alors vraiment, qu'aurait C sur un bon assembleur tel que NASM?

Edit: Juste pour souligner. Lorsque vous écrivez en assembleur, vous n'avez pas à écrire uniquement dans les codes d'instructions. Vous pouvez utiliser des macros et des procédures et vos propres conventions pour créer diverses abstractions afin de rendre les programmes plus modulaires, plus faciles à gérer et plus faciles à lire. C'est là qu'intervient la façon d'écrire un bon assemblage.


71
Écrire ? Et la lecture du code? vous (et d'autres) lirez le code beaucoup plus que vous ne l'écrivez
nos

81
Pourquoi devrais-je avoir à apprendre une nouvelle langue simplement parce que mon programme doit s'exécuter sur une nouvelle plateforme? Pourquoi devrais-je avoir à construire mes programmes pour s'adapter à l'idée du processeur sur le nombre de registres et ce que vous pouvez en faire? J'essaie de résoudre les problèmes, pas les enchères d'ordinateurs.
Joachim Sauer

8
Résumé de l'EDIT: On peut utiliser un compilateur C.
Meinersbur

4
@Simon J'ai peut-être mal mes années alors, mais je suis surpris que nous débattions de l'ASM contre "un langage de haut niveau comme C" en 2010. Plus précisément la partie où C est l'exemple d'un langage de haut niveau
matt b

11
@changelog: Ce n'est pas comme ça que vous épelez programmation.reddit.com.
BoltClock

Réponses:


331

ASM a une faible lisibilité et n'est pas vraiment maintenable par rapport aux langages de niveau supérieur.

En outre, il y a beaucoup moins de développeurs ASM que pour d'autres langages plus populaires, tels que C.

De plus, si vous utilisez un langage de niveau supérieur et que de nouvelles instructions ASM deviennent disponibles (SSE par exemple), il vous suffit de mettre à jour votre compilateur et votre ancien code peut facilement utiliser les nouvelles instructions.

Et si le prochain CPU a deux fois plus de registres?

L'inverse de cette question serait: quelle fonctionnalité les compilateurs offrent-ils?

Je doute que vous puissiez / souhaitiez / devriez optimiser votre ASM mieux que gcc -O3possible.


10
gcc n'est pas si bon en optimisation, bien meilleur que l'homme moyen, mais il y a de nombreux endroits où les optimiseurs ne font pas du bon travail. D'accord avec vous, sinon.
old_timer

4
@dwelch Dans de très rares cas, gcc (ou de nombreux autres compilateurs) ne parvient pas à optimiser correctement le C. compilé. Dans ces cas, cependant, vous pouvez toujours écrire un nombre limité de procédures dans ASM et lier uniquement ces méthodes pendant la génération.
cortijon

@Ben S: J'ai d'abord édité en "beaucoup" plutôt qu'en "beaucoup" car "beaucoup" est utilisé uniquement pour les objets singuliers. Puisque l'objet de "much" est pluriel (développeurs), "many" est l'option correcte. Mais je ne modifierai plus votre réponse si "beaucoup" est ce que vous voulez.
Billy ONeal

1
Il existe de nombreux cas où un compilateur ne peut pas bien optimiser, mais très souvent, un développeur conscient des limites de l'optimiseur peut optimiser son code C sans recourir à l'assembly.
Qwertie

1
FWIW dans mon travail de jour, je compile notre produit avec gcc -g -O0, parce que pouvoir y attacher gdb sur un système en direct et ne pas devenir fou en raison de variables optimisées hors de l'existence, vaut beaucoup plus pour le entreprise que ce ne serait de laisser un autre 4 milliards de cycles de CPU inactifs chaque jour (sur un total de 3 billions). Crunching entiers n'est tout simplement pas le goulot d'étranglement très souvent.
Bernd Jendrissek

1930

Hell®, je suis un compilateur.

Je viens de scanner des milliers de lignes de code pendant que vous lisiez cette phrase. J'ai parcouru des millions de possibilités d'optimiser une seule ligne de la vôtre en utilisant des centaines de techniques d'optimisation différentes basées sur une grande quantité de recherches universitaires auxquelles vous consacreriez des années. Je ne ressentirai aucune gêne, pas même une légère ick, lorsque je convertirai une boucle de trois lignes en milliers d'instructions juste pour la rendre plus rapide. Je n'ai aucune honte à aller trop loin dans l'optimisation ou à faire les trucs les plus sales. Et si vous ne voulez pas que je le fasse, peut-être pendant un jour ou deux, je vais me comporter et le faire comme vous le souhaitez. Je peux transformer les méthodes que j'utilise à tout moment, sans même changer une seule ligne de votre code. Je peux même vous montrer à quoi ressemblerait votre code en assembleur, sur différentes architectures de processeur et différents systèmes d'exploitation et dans différentes conventions d'assemblage si vous le souhaitez. Oui, tout cela en quelques secondes. Parce que, vous savez, je peux; et vous savez, vous ne pouvez pas.

PS Oh, d'ailleurs vous n'utilisiez pas la moitié du code que vous avez écrit. Je t'ai rendu service et l'ai jeté.


99

J'ai écrit des décharges d'assembleur pour les puces 6502, Z80, 6809 et 8086. J'ai cessé de le faire dès que les compilateurs C sont devenus disponibles pour les plates-formes auxquelles je m'adressais, et suis immédiatement devenu au moins 10 fois plus productif. La plupart des bons programmeurs utilisent les outils qu'ils utilisent pour des raisons rationnelles.


72

J'adore la programmation en langage assembleur, mais il faut plus de code pour faire la même chose que dans un langage de haut niveau, et il y a une corrélation directe entre les lignes de code et les bugs. (Cela a été expliqué il y a des décennies dans The Mythical Man-Month .)

Il est possible de penser à C comme un «assemblage de haut niveau», mais franchissez quelques étapes au-dessus de cela et vous êtes dans un monde différent. En C # vous ne pensez pas à deux fois avant d'écrire ceci:

foreach (string s in listOfStrings) { /* do stuff */ }

Ce serait des dizaines, peut-être des centaines de lignes de code dans l'assemblage, chaque programmeur qui l'implémenterait adopterait une approche différente, et la prochaine personne à venir devrait le comprendre. Donc, si vous croyez (comme beaucoup le font) que les programmes sont écrits principalement pour être lus par d'autres personnes, l'assemblage est moins lisible que le HLL typique.

Edit: J'ai accumulé une bibliothèque personnelle de code utilisé pour les tâches courantes et des macros pour implémenter des structures de contrôle de type C. Mais j'ai frappé le mur dans les années 90, lorsque les interfaces graphiques sont devenues la norme. Trop de temps était consacré à des choses qui étaient routinières.

La dernière tâche que j'ai eue où ASM était essentiel était il y a quelques années, écrire du code pour lutter contre les logiciels malveillants. Pas d'interface utilisateur, donc c'était toutes les parties amusantes sans le ballonnement.


Êtes-vous sûr de cela? Il me semble avoir lu dans Code Complete que ce n'était pas le cas ...
jcolebrand

1
Je suis sûr qu'il y a un point où l'avantage «moins de lignes» est battu par l'inconvénient «optimisation prématurée». Mais je n'ai pas regardé Code Complete depuis des lustres ...
egrunin

6
Un peu ironique d'utiliser "l'optimisation prématurée" comme argument pour l' assemblage ... (Je vous ai probablement mal interprété cependant. Je pense toujours que c'est drôle.)
Bernd Jendrissek

Vous pouvez toujours appeler la fonction dans l'assembleur, donc je doute qu'une boucle foreach prenne des dizaines à des centaines de lignes. Ou qu'est-ce qui me manque?
Sebastian Mach

@phresnel: foreachfait beaucoup plus de travail que for- il instancie et utilise un itérateur spécifique au type.
egrunin

15

En plus des réponses des autres concernant la lisibilité, la maintenabilité, le code plus court et donc moins de bugs, et étant beaucoup plus facile, j'ajouterai une raison supplémentaire:

vitesse du programme.

Oui, lors de l'assemblage, vous pouvez régler manuellement votre code pour utiliser chaque dernier cycle et le rendre aussi rapide que possible physiquement. Mais qui a le temps? Si vous écrivez un programme C pas complètement stupide, le compilateur fera un excellent travail d'optimisation pour vous. Faire probablement au moins 95% des optimisations que vous feriez à la main, sans avoir à vous soucier de garder une trace de tout cela. Il y a certainement une sorte de règle 90/10 ici, où les derniers 5% d'optimisations finiront par prendre 95% de votre temps. Alors pourquoi s'embêter?


4
+1. Écrire du code assembleur et écrire du code assembleur rapide sont deux choses différentes. Si vous utilisez un bon compilateur, vous obtenez gratuitement le code de l'assembleur rapide.
Niki

vous obtenez du code d'assembleur rapide gratuitement uniquement si vous savez comment utiliser le compilateur, la plupart n'utilisent pas l'optimisation, la plupart des gens compilent avec des options de débogage et en conséquence se retrouvent avec un assembleur lent mal fait. oui plus de 99% du temps, vous ne devriez pas le toucher, il suffit de toucher les boutons du compilateur et de ne pas modifier directement la sortie.
old_timer

si vous vous souciez des optimisations, alors vous devriez le faire à partir du compilateur ... SI vous ne vous souciez pas des optimisations, mais vous utilisez toujours l'assemblage, alors vous êtes juste stupide.
Brian Postow

@dwelch: Je suppose qu'il pourrait y avoir des script-kiddies qui ne se soucient pas de savoir comment leurs outils sont utilisés. Mais je doute que des gens comme eux soient capables d'écrire du code d'assembleur rapide.
Niki

13

Si un programme de production moyen a disons 100 000 lignes de code et que chaque ligne contient environ 8 à 12 instructions d'assembleur, cela représenterait 1 million d'instructions d'assembleur.

Même si vous pouviez écrire tout cela à la main à une vitesse décente (rappelez-vous, c'est 8 fois plus de code que vous devez écrire), que se passe-t-il si vous souhaitez modifier certaines fonctionnalités? Comprendre quelque chose que vous avez écrit il y a quelques semaines sur ces 1 million d'instructions est un cauchemar! Il n'y a pas de modules, pas de classes, pas de conception orientée objet, pas de frameworks, rien du tout. Et la quantité de code similaire que vous devez écrire pour les choses les plus simples est au mieux intimidante.

De plus, vous ne pouvez pas optimiser votre code presque aussi bien qu'un langage de haut niveau. Lorsque C par exemple effectue un nombre fou d'optimisations parce que vous décrivez votre intention, pas seulement votre code, dans l'assembleur vous écrivez uniquement du code, l'assembleur ne peut pas vraiment effectuer des optimisations dignes de mention sur votre code. Ce que vous écrivez est ce que vous obtenez, et croyez-moi, vous ne pouvez pas optimiser de manière fiable 1 million d'instructions que vous corrigez et corrigez au fur et à mesure que vous l'écrivez.


8

Eh bien, j'écris beaucoup d'assemblages "dans l'ancien temps", et je peux vous assurer que je suis beaucoup plus productif lorsque j'écris des programmes dans un langage de haut niveau.


8
"L'assemblée est latine".
Adriano Varoli Piazza

4
@Adriano: sauf qu'il existe de nombreux dialectes différents et qu'il n'y en a pas deux qui se ressemblent.
Joachim Sauer

1
Bien sûr, mais je voulais dire que l'apprentissage de la programmation dans l'un d'eux vous donne un aperçu de l'architecture d'une machine qui vous aide à des niveaux supérieurs. Sauf si vous traitez avec la mémoire paginée, dans ce cas, vous vous retrouvez marqué. Comme lire Carmen 16 de Catullus.
Adriano Varoli Piazza

5
@Adriano "Assembly is Latin", No asm is caveman grunts. Un grognement pour le rock 2 grognements pour les cerfs, 3 grognements pour le feu - bon pour les trucs simples mais difficile à diriger un empire.
Martin Beckett

1
@Martin: Avez-vous déjà essayé de faire de l'arithmétique complexe avec des chiffres romains?
Adriano Varoli Piazza

6

Un niveau raisonnable de compétence assembleur est une compétence utile, surtout si vous travaillez à toute sorte de niveau système ou la programmation embarquée, non pas tant parce que vous devez écrire beaucoup assembleur, mais parce que parfois il est important de comprendre ce que la boîte est vraiment en train de faire . Si vous n'avez pas une compréhension de bas niveau des concepts et des problèmes des assembleurs, cela peut être très difficile.

Cependant, comme pour écrire réellement beaucoup de code dans l'assembleur, il y a plusieurs raisons pour lesquelles ce n'est pas beaucoup fait.

  • Il n'y a tout simplement pas (presque) besoin. À l'exception de quelque chose comme l'initialisation très précoce du système et peut-être quelques fragments d'assembleur cachés dans des fonctions C ou des macros, tout le code de très bas niveau qui aurait pu être écrit dans l'assembleur peut être écrit en C ou C ++ sans difficulté.

  • Le code dans les langages de niveau supérieur (même C et C ++) condense la fonctionnalité en beaucoup moins de lignes, et des recherches considérables montrent que le nombre de bogues est en corrélation avec le nombre de lignes de code source. C'est-à-dire que le même problème, résolu dans l'assembleur et C, aura plus de bogues dans l'assembleur simplement parce que c'est plus long. Le même argument motive le passage à des langages de niveau supérieur tels que Perl, Python, etc.

  • En écrivant dans l'assembleur, vous devez gérer tous les aspects du problème, de la disposition détaillée de la mémoire, la sélection des instructions, les choix d'algorithmes, la gestion de la pile, etc. Les langages de niveau supérieur vous enlèvent tout cela, c'est pourquoi sont tellement plus denses dans termes de LOC.

Essentiellement, tout ce qui précède est lié au niveau d'abstraction dont vous disposez dans l'assembleur par rapport à C ou à un autre langage. L'assembleur vous oblige à faire toutes vos propres abstractions et à les maintenir à travers votre propre autodiscipline, où tout langage de niveau intermédiaire comme C, et en particulier les langages de niveau supérieur, vous fournit des abstractions hors de la boîte, ainsi que le possibilité d'en créer de nouveaux assez facilement.


6

En tant que développeur qui passe la plupart de son temps dans le monde de la programmation embarquée, je dirais que l'assemblage est loin d'être un langage mort / obsolète. Il existe un certain niveau de codage proche du métal (par exemple, dans les pilotes) qui ne peut parfois pas être exprimé avec autant de précision ou d'efficacité dans un langage de niveau supérieur. Nous écrivons presque toutes nos routines d'interface matérielle dans l'assembleur.

Cela étant dit, ce code assembleur est encapsulé de sorte qu'il peut être appelé à partir du code C et est traité comme une bibliothèque. Nous n'écrivons pas l'intégralité du programme en assembleur pour de nombreuses raisons. La portabilité est avant tout; notre base de code est utilisée sur plusieurs produits qui utilisent différentes architectures et nous voulons maximiser la quantité de code qui peut être partagée entre eux. La deuxième est la familiarité des développeurs. Autrement dit, les écoles n'enseignent pas l'assemblage comme avant, et nos développeurs sont beaucoup plus productifs en C qu'en assemblage. De plus, nous avons une grande variété d '"extras" (des choses comme des bibliothèques, des débogueurs, des outils d'analyse statique, etc.) disponibles pour notre code C qui ne sont pas disponibles pour le code du langage assembleur. Même si nous voulions écrire un programme d'assemblage pur, nous ne serions pas en mesure de le faire car plusieurs bibliothèques matérielles critiques ne sont disponibles que sous forme de bibliothèques C. Dans un sens, c'est un problème de poulet / œuf. Les gens sont éloignés de l'assembly car il n'y a pas autant de bibliothèques et d'outils de développement / débogage disponibles, mais les bibliothèques / outils n'existent pas car pas assez de gens utilisent l'assembly pour justifier l'effort de les créer.

En fin de compte, il y a un temps et une place pour à peu près n'importe quelle langue. Les gens utilisent ce qu'ils connaissent le mieux et le plus productif. Il y aura probablement toujours une place dans le répertoire d'un programmeur pour l'assemblage, mais la plupart des programmeurs trouveront qu'ils peuvent écrire du code dans un langage de niveau supérieur qui est presque aussi efficace en beaucoup moins de temps.


6

Lorsque vous écrivez en assembleur, vous n'avez pas à écrire uniquement dans les codes d'instructions. Vous pouvez utiliser des macros et des procédures et vos propres conventions pour créer diverses abstractions afin de rendre les programmes plus modulaires, plus faciles à gérer et plus faciles à lire.

Donc, ce que vous dites essentiellement, c'est qu'avec l'utilisation habile d'un assembleur sophistiqué, vous pouvez rendre votre code ASM de plus en plus proche de C (ou de toute façon un autre langage de bas niveau de votre propre invention), jusqu'à ce que finalement vous soyez juste aussi productif qu'un programmeur C.

Est-ce que ça répond à votre question? ;-)

Je ne dis pas cela paresseusement: j'ai programmé en utilisant exactement un tel assembleur et système. Encore mieux, l'assembleur pourrait cibler un processeur virtuel, et un traducteur séparé a compilé la sortie de l'assembleur pour une plate-forme cible. Tout comme cela se produit avec l'IF de LLVM, mais dans ses premières formes, il était antérieur à environ 10 ans. Il y avait donc la portabilité, plus la possibilité d'écrire des routines pour un assembleur cible spécifique là où cela était nécessaire pour l'efficacité.

L'écriture à l'aide de cet assembleur était à peu près aussi productive que C, et en comparaison avec GCC-3 (qui existait au moment où j'étais impliqué), l'assembleur / traducteur a produit un code à peu près aussi rapide et généralement plus petit. La taille était vraiment importante, et l'entreprise avait peu de programmeurs et était disposée à enseigner aux nouveaux employés une nouvelle langue avant de pouvoir faire quoi que ce soit d'utile. Et nous avions la sauvegarde que les personnes qui ne connaissaient pas l'assembleur (par exemple les clients) pouvaient écrire C et le compiler pour le même processeur virtuel, en utilisant la même convention d'appel et ainsi de suite, afin qu'il s'interface parfaitement. Cela ressemblait donc à une victoire marginale.

C'était avec plusieurs années-homme de travail dans le sac pour développer la technologie d'assemblage, les bibliothèques, etc. Certes, une grande partie a été consacrée à le rendre portable, s'il n'avait ciblé qu'une seule architecture, alors l'assembleur tout-chantant et dansant aurait été beaucoup plus facile.

En résumé: vous n'aimez peut-être pas C, mais cela ne signifie pas que l'effort d'utiliser C est plus important que celui de trouver quelque chose de mieux.


5

L'assemblage n'est pas portable entre différents microprocesseurs.


Ce n'est pas exactement le cas avec les processeurs et les programmes d'assemblage modernes, vous pouvez cibler différents processeurs comme vous le pouvez en C. Bien sûr, vous ne pourrez pas utiliser l'ensemble complet des instructions dans ce cas, mais vous ne le ferez pas non plus si vous l'écrivez en C. La portabilité n'est pas la principale préoccupation.
Blindy

6
Peut-être que vous parlez d' architecture .
Ben S

2
@Blindy - Vous pouvez cibler différents processeurs au sein de la famille x86 mais il n'y a certainement aucun point commun dans les instructions d'assemblage entre une variante x86 et un processeur ARM ou un Z80 ou un 8051.
semaj

Certes, mais vous ne pouvez pas non plus programmer un z80 en c. Je pense que nous parlons tous ici de processeurs x86 / x64 normaux.
Blindy

1
Tout le monde n'est pas un x86. Rien sur les "microprocesseurs différents" ne suggère qu'ils exécutent tous le même jeu d'instructions.
Bernd Jendrissek

5

La même raison pour laquelle nous n'allons plus aux toilettes à l'extérieur, ou pourquoi nous ne parlons pas latin ou araméen.

La technologie arrive et rend les choses plus faciles et plus accessibles.

EDIT - pour cesser d'offenser les gens, j'ai supprimé certains mots.


4
Vous Technology
offensez

1
"Nous" ne parlons pas latin?
dank

Ni le latin ni l'araméen n'ont disparu car ils ont été remplacés par une meilleure technologie (c'est-à-dire une langue plus facile à apprendre / à apprendre). En fait, le latin est toujours avec nous partout en Europe. Toutes les langues romaines sont basées sur le latin. L'araméen (néo) moderne est parlé par près d'un demi-million de personnes aujourd'hui. Les raisons pour lesquelles ces langues ne sont plus répandues sont historiques (géopolitiques, pour être plus précis), pas technologiques. La même raison pour laquelle l'anglais est la lingua franca de la science et des classes dirigeantes de notre époque - les gens du dernier empire, les Britanniques (et maintenant les États-Unis d'Amérique) le parlent.
le Ritz

4

Pourquoi? Facile.

Comparez ceci:

        for (var i = 1; i <= 100; i++)
        {
            if (i % 3 == 0)
                Console.Write("Fizz");
            if (i % 5 == 0)
                Console.Write("Buzz");
            if (i % 3 != 0 && i % 5 != 0)
                Console.Write(i);
            Console.WriteLine();
        }

avec

.locals init (
    [0] int32 i)
L_0000: ldc.i4.1 
L_0001: stloc.0 
L_0002: br.s L_003b
L_0004: ldloc.0 
L_0005: ldc.i4.3 
L_0006: rem 
L_0007: brtrue.s L_0013
L_0009: ldstr "Fizz"
L_000e: call void [mscorlib]System.Console::Write(string)
L_0013: ldloc.0 
L_0014: ldc.i4.5 
L_0015: rem 
L_0016: brtrue.s L_0022
L_0018: ldstr "Buzz"
L_001d: call void [mscorlib]System.Console::Write(string)
L_0022: ldloc.0 
L_0023: ldc.i4.3 
L_0024: rem 
L_0025: brfalse.s L_0032
L_0027: ldloc.0 
L_0028: ldc.i4.5 
L_0029: rem 
L_002a: brfalse.s L_0032
L_002c: ldloc.0 
L_002d: call void [mscorlib]System.Console::Write(int32)
L_0032: call void [mscorlib]System.Console::WriteLine()
L_0037: ldloc.0 
L_0038: ldc.i4.1 
L_0039: add 
L_003a: stloc.0 
L_003b: ldloc.0 
L_003c: ldc.i4.s 100
L_003e: ble.s L_0004
L_0040: ret 

Ils sont identiques en termes de fonctionnalités. Le second n'est même pas assembleur mais .NET IL (Intermediary Language, similaire au bytecode de Java). La deuxième compilation transforme l'IL en code natif (c'est-à-dire presque assembleur), le rendant encore plus cryptique.


3

Je suppose que ASM même sur x86 (_64) est logique dans les cas où vous gagnez beaucoup en utilisant des instructions difficiles à optimiser pour un compilateur. x264, par exemple, utilise beaucoup d'asm pour son encodage, et les gains de vitesse sont énormes.


2

Je suis sûr qu'il existe de nombreuses raisons, mais deux raisons rapides auxquelles je peux penser sont

  1. Le code d'assemblage est certainement plus difficile à lire (je suis certain que son écriture prend également plus de temps)
  2. Lorsque vous avez une énorme équipe de développeurs travaillant sur un produit, il est utile de diviser votre code en blocs logiques et de le protéger par des interfaces.

1
Notez que vous pouvez également séparer l'assemblage en blocs logiques.
Paul Williams

2

L'une des premières découvertes (que vous trouverez dans le Mythical Man-Month de Brooks , qui provient de l'expérience des années 1960) était que les gens étaient plus ou moins aussi productifs dans une langue que dans une autre, dans des lignes de code déboguées par jour. Ce n'est évidemment pas universellement vrai, et peut se briser lorsqu'il est poussé trop loin, mais c'était généralement vrai pour les langages de haut niveau de l'époque de Brooks.

Par conséquent, le moyen le plus rapide d'obtenir de la productivité serait d'utiliser des langages où une ligne de code individuelle a fait plus, et en effet cela fonctionne, au moins pour les langages de complexité comme FORTRAN et COBOL, ou de donner un exemple plus moderne C.


2

La portabilité est toujours un problème - sinon maintenant, du moins à terme. L'industrie de la programmation dépense des milliards chaque année pour porter de vieux logiciels qui, au moment où ils ont été écrits, n'avaient "évidemment" aucun problème de portabilité.


2
"Il n'aura pas à porter sur une autre architecture" me semble beaucoup comme "Il n'aura pas besoin de plus de deux chiffres pour l'année".
David Thornley

Ou nous ne pouvons pas utiliser C # parce que Windows pourrait ne pas être là l'année prochaine?
Martin Beckett

Par exemple, les ordinateurs MacIntosh d'Apple, basés sur les processeurs Motorola MC68000, PowerPC (IBM et tous) et maintenant les processeurs x86 (IA-32 (e)) d'Intel. Donc oui, la portabilité est un problème pour tout système utilisé assez longtemps, et tout programmeur qui n'a pas été mordu par son code pendant plus longtemps que prévu n'est pas encore expérimenté.
mctylr

@Martin: Dans vingt ans, il y aura beaucoup de programmes C # que les gens voudront exécuter, et donc il y aura un moyen de compiler et d'exécuter des programmes C #. Il n'y a rien de intrinsèquement fixé à propos de C #, bien que dans vingt ans, je serais surpris s'il était toujours aussi populaire qu'aujourd'hui. Cependant, dans vingt ans, nos processeurs seront sensiblement différents. Un programme assembleur écrit en 1990 pourrait bien fonctionner de nos jours, mais il ne sera certainement pas optimal, et fonctionnera plus lentement que compilé C.
David Thornley

C'est ce que je voulais dire - j'ai beaucoup plus de problèmes de portage parce qu'un framework de haut niveau a changé depuis 6 mois que je ne le fais parce que les instructions dans un x86 ont changé - d'autant plus que l'asm codé à la main a tendance à s'en tenir aux méthodes les plus simples.
Martin Beckett

2

Il y avait un cercle vicieux à mesure que l'assemblage devenait moins courant: à mesure que les langages de niveau supérieur arrivaient à maturité, les ensembles d'instructions de langage d'assemblage étaient construits moins pour la commodité du programmeur et plus pour la commodité des compilateurs.

Alors maintenant, de façon réaliste, il peut être très difficile de prendre les bonnes décisions sur, disons, les registres que vous devez utiliser ou les instructions qui sont légèrement plus efficaces. Les compilateurs peuvent utiliser des heuristiques pour déterminer quels compromis sont susceptibles d'avoir le meilleur rendement. Nous pouvons probablement réfléchir à des problèmes plus petits et trouver des optimisations locales qui pourraient battre nos compilateurs désormais assez sophistiqués, mais il y a de fortes chances que dans le cas moyen, un bon compilateur fasse un meilleur travail du premier coup qu'un bon programmeur le fera probablement. Finalement, comme John Henry, nous pourrions battre la machine, mais nous pourrions nous brûler sérieusement pour y arriver.

Nos problèmes sont également maintenant très différents. En 1986, j'essayais de comprendre comment obtenir un peu plus de vitesse avec les petits programmes qui impliquaient de mettre quelques centaines de pixels sur l'écran; Je voulais que l'animation soit moins saccadée. Un cas juste pour le langage d'assemblage. Maintenant, j'essaie de comprendre comment représenter les abstractions autour du langage contractuel et de la politique de service pour les hypothèques, et je préfère lire quelque chose qui ressemble beaucoup à la langue parlée par les gens d'affaires. Contrairement aux macros LISP, les macros d'assemblage n'appliquent pas beaucoup de règles, donc même si vous pouvez obtenir quelque chose de raisonnablement proche d'une DSL dans un bon assembleur, il sera sujet à toutes sortes de bizarreries qui gagneront '' Cela ne me pose pas de problèmes si j'écris le même code en Ruby, Boo, Lisp, C # ou même F #.

Si vos problèmes sont faciles à exprimer dans un langage d'assemblage efficace, plus de puissance pour vous.


2

Idem la plupart de ce que les autres ont dit.

Dans le bon vieux temps avant que C ne soit inventé, lorsque les seuls langages de haut niveau étaient des choses comme COBOL et FORTRAN, il y avait beaucoup de choses qui n'étaient tout simplement pas possibles sans recourir à l'assembleur. C'était le seul moyen d'obtenir toute l'étendue de la flexibilité, de pouvoir accéder à tous les appareils, etc. Mais ensuite C a été inventé, et presque tout ce qui était possible en assemblage était possible en C.J'ai écrit très peu d'assemblage depuis puis.

Cela dit, je pense que c'est un exercice très utile pour les nouveaux programmeurs d'apprendre à écrire en assembleur. Non pas parce qu'ils l'utilisent beaucoup, mais parce que vous comprenez alors ce qui se passe réellement à l'intérieur de l'ordinateur. J'ai vu beaucoup d'erreurs de programmation et de code inefficace de programmeurs qui n'ont clairement aucune idée de ce qui se passe réellement avec les bits et octets et les registres.


Oui, repérez. Il y a des années, les E / S de disque et de bande Fortran sur les mainframes IBM étaient presque inutiles, nous avons donc écrit nos propres routines d'E / S dans 370 / Assembler et les avons appelées à partir du code Fortan IV. Et l'écriture du code assembleur m'a fait vraiment comprendre l'architecture sous-jacente. Je n'ai pas écrit de code d'assemblage depuis quelques années et tous les jeunes avec qui je travaille n'en ont jamais écrit - mais j'aurais aimé qu'ils le fassent, c'est tellement éducatif.
Simon Knights

2

Je programme en assembleur depuis environ un mois. J'écris souvent un morceau de code en C, puis je le compile en assembleur pour m'aider. Peut-être que je n'utilise pas la pleine puissance d'optimisation du compilateur C, mais il semble que ma source C asm inclut des opérations inutiles. Je commence donc à voir que le discours d'un bon compilateur C surpassant un bon codeur d'assemblage n'est pas toujours vrai.

Quoi qu'il en soit, mes programmes d'assemblage sont si rapides. Et plus j'utilise l'assemblage, moins il me faut de temps pour écrire mon code car ce n'est vraiment pas si difficile. De plus, le commentaire sur l'assemblage ayant une mauvaise lisibilité n'est pas vrai. Si vous étiquetez vos programmes correctement et faites des commentaires lorsqu'une élaboration supplémentaire est nécessaire, vous devriez être prêt. En fait, l'assemblage est plus clair pour le programmeur car il voit ce qui se passe au niveau du processeur. Je ne connais pas les autres programmeurs mais pour moi j'aime savoir ce qui se passe, plutôt que les choses étant dans une sorte de boîte noire.

Cela dit, le véritable avantage des compilateurs est qu'un compilateur peut comprendre les modèles et les relations, puis les coder automatiquement aux emplacements appropriés dans la source. Un exemple populaire est les fonctions virtuelles en C ++ qui nécessitent que le compilateur mappe de manière optimale les pointeurs de fonction. Cependant, un compilateur se limite à faire ce que le fabricant du compilateur permet au compilateur de faire. Cela conduit les programmeurs à parfois avoir à faire des choses bizarres avec leur code, en ajoutant du temps de codage, alors qu'ils auraient pu être faits trivialement avec l'assemblage.

Personnellement, je pense que le marché prend fortement en charge les langues de haut niveau. Si le langage d'assemblage était le seul langage existant aujourd'hui, leur programmation serait d'environ 70% inférieure et qui sait où serait notre monde, probablement dans les années 90. Les langues de niveau supérieur font appel à un éventail plus large de personnes. Cela permet à un plus grand nombre de programmeurs de construire l'infrastructure nécessaire de notre monde. Les pays en développement comme la Chine et l'Inde bénéficient largement de langages comme Java. Ces pays développeront rapidement leur infrastructure informatique et les gens deviendront plus interconnectés. Mon point est donc que les langages de haut niveau sont populaires non pas parce qu'ils produisent un code supérieur mais parce qu'ils aident à répondre à la demande sur les marchés mondiaux.


+1 pour la boîte noire. Oui, nous utilisons des boîtes noires, et il n'y a aucun moyen d'y jeter un œil (trop facile). Comment fonctionne réellement C # foreach ? Qui sait. Microsoft a dit que c'était parfait. Alors ça doit être.
ern0

N'oubliez pas non plus qu'avec un «langage de haut niveau», il y a beaucoup d'autres choses qui comptent dans le monde réel. C est livré avec les bibliothèques standard (mathématiques, traitement de chaînes, E / S, etc.), puis les poids lourds comme Java sont livrés avec de nombreux autres packages et bibliothèques pour la connectivité, le traitement d'image, le traitement des données, le développement Web, etc. C'est une question d'utiliser votre temps pour vous concentrer sur l'obtention d'une tâche détaillée hautement performante sur une seule plate-forme (en utilisant ainsi l'assemblage) au lieu de passer le même temps à exécuter une tâche beaucoup plus grande sur plusieurs plates-formes avec un minimum de bogues.
jbx

1

J'apprends l'assemblage dans org comp en ce moment, et bien que ce soit intéressant, il est également très inefficace d'écrire. Vous devez garder beaucoup plus de détails dans votre tête pour que les choses fonctionnent, et c'est aussi plus lent pour écrire les mêmes choses . Par exemple, une simple boucle de 6 lignes en C ++ peut correspondre à 18 lignes ou plus d'assemblage.

Personnellement, c'est très amusant d'apprendre comment les choses fonctionnent au niveau matériel, et cela me donne une meilleure appréciation du fonctionnement de l'informatique.


1

Ce que C a sur un bon assembleur de macros est le langage C. Vérification de type. Constructions en boucle. Gestion automatique de la pile. (Presque) gestion automatique des variables. Les techniques de mémoire dynamique dans l'assembleur sont une douleur énorme dans le cul. Faire correctement une liste chaînée est tout simplement effrayant par rapport à C ou mieux encore listez foo.insert (). Et le débogage - eh bien, il n'y a pas de concours sur ce qui est plus facile à déboguer. Les HLL y gagnent haut la main.

J'ai codé près de la moitié de ma carrière d'assembleur ce qui me permet de penser très facilement en assmebler. cela m'aide à voir ce que fait le compilateur C, ce qui m'aide à nouveau à écrire du code que le compilateur C peut gérer efficacement. Une routine bien pensée écrite en C peut être écrite pour produire exactement ce que vous voulez dans l'assembleur avec un peu de travail - et c'est portable! J'ai déjà dû réécrire quelques anciennes routines asm en C pour des raisons multiplateformes et ce n'est pas amusant.

Non, je vais m'en tenir à C et gérer le léger ralentissement occasionnel des performances par rapport au temps de productivité que je gagne avec HLL.


1

Je peux seulement expliquer pourquoi je n'écris pas plus souvent de programmes en assembleur, et la raison principale est que c'est plus fastidieux à faire. De plus, je pense qu'il est plus facile de se tromper subtilement sans s'en apercevoir immédiatement. Par exemple, vous pouvez changer la façon dont vous utilisez un registre dans une routine mais oubliez de le changer en un seul endroit. Il s'assemblera très bien et vous ne le remarquerez peut-être que bien plus tard.

Cela dit, je pense qu'il existe encore des utilisations valides pour l'assemblage. Par exemple, j'ai un certain nombre de routines d'assemblage assez optimisées pour traiter de grandes quantités de données, en utilisant SIMD et en suivant l'approche paranoïaque "chaque bit est sacré" [citation V.Stob]. (Mais notez que les implémentations d'assemblages naïfs sont souvent bien pires que ce qu'un compilateur générerait pour vous.)


1

C est un macro assembleur! Et c'est le meilleur!

Il peut faire presque tout ce que l'assembly peut faire, il peut être portable et dans la plupart des rares cas où il ne peut pas faire quelque chose, vous pouvez toujours utiliser le code d'assembly intégré. Cela ne laisse qu'une petite fraction des programmes que vous devez absolument écrire dans l'assemblage et rien que l'assemblage.

Et les abstractions de niveau supérieur et la portabilité rendent plus intéressant pour la plupart des gens d'écrire des logiciels système en C. Et bien que vous n'ayez peut-être pas besoin de portabilité maintenant si vous investissez beaucoup de temps et d'argent dans l'écriture d'un programme, vous ne voudrez peut-être pas vous limiter dans ce que vous pourrez l'utiliser à l'avenir.


1

Les gens semblent oublier qu'il y a aussi l'autre sens.

Pourquoi écrivez-vous dans Assembler en premier lieu? Pourquoi ne pas écrire le programme dans une langue de bas niveau?

Au lieu de

mov eax, 0x123
add eax, 0x456
push eax
call printInt

vous pourriez aussi bien écrire

B823010000
0556040000
50 
FF15.....

Cela a tellement d' avantages, vous connaissez la taille exacte de votre programme, vous pouvez réutiliser la valeur des instructions comme entrée pour d'autres instructions et vous n'avez même pas besoin d'un assembleur pour l'écrire, vous pouvez utiliser n'importe quel éditeur de texte ...

Et la raison pour laquelle vous préférez encore Assembler à ce sujet, c'est la raison pour laquelle d'autres personnes préfèrent C ...


0

Parce que c'est toujours comme ça: le temps passe et les bonnes choses passent aussi :(

Mais lorsque vous écrivez du code asm, c'est une sensation totalement différente de celle que vous codez des langages de haut niveau, bien que vous sachiez que c'est beaucoup moins productif. C'est comme si vous étiez un peintre: vous êtes libre de dessiner tout ce que vous aimez comme vous le souhaitez sans aucune restriction (enfin, uniquement par les fonctionnalités du CPU) ... C'est pourquoi je l'adore. Dommage que cette langue disparaisse. Mais alors que quelqu'un s'en souvient et le code, il ne mourra jamais!


Vrai. D'un autre côté, il y a l'humiliation que vous ressentez lorsque le caissier et le supermarché refusent d'encaisser votre chèque, en disant avec dédain: «Oh, vous programmez dans une langue de bas niveau».
Jay

0

$$$

Une entreprise engage un développeur pour aider à transformer le code en $$$. Plus le code utile peut être produit rapidement, plus l'entreprise peut transformer ce code en $$$ rapidement.

Les langages de niveau supérieur sont généralement meilleurs pour produire de plus gros volumes de code utile. Cela ne veut pas dire que l'assemblée n'a pas sa place, car il y a des moments et des endroits où rien d'autre ne fera.


0

L'avantage des HLL est encore plus important lorsque vous comparez l'assembly à un langage de niveau supérieur à C, par exemple Java ou Python ou Ruby. Par exemple, ces langages ont une récupération de place: pas besoin de se soucier du moment où libérer un morceau de mémoire, et pas de fuites de mémoire ou de bugs en raison d'une libération trop précoce.


0

Comme d'autres l'ont déjà mentionné, la raison pour laquelle un outil existe est son efficacité. Comme les HLL peuvent accomplir les mêmes tâches que de nombreuses lignes de code asm, je suppose qu'il est naturel que l'assembly soit remplacé par d'autres langages. Et pour le violon proche du matériel - il existe un assemblage en ligne en C et d'autres variantes selon le langage. Le Dr Paul Carter dit dans le langage d'assemblage PC

"... une meilleure compréhension du fonctionnement réel des ordinateurs à un niveau inférieur à celui des langages de programmation comme Pascal. En acquérant une meilleure compréhension du fonctionnement des ordinateurs, le lecteur peut souvent être beaucoup plus productif en développant des logiciels dans des langages de plus haut niveau tels que C et C ++. Apprendre à programmer en langage assembleur est un excellent moyen d'atteindre cet objectif. "

Nous avons une introduction à l'assemblage dans mes cours universitaires. Cela aidera à clarifier les concepts. Cependant, je doute qu'aucun d'entre nous n'écrive 90% du code en assembleur. Quelle est la pertinence des connaissances approfondies en assemblage aujourd'hui?


-2

En feuilletant ces réponses, je parie que 9/10 des répondants n'ont jamais travaillé avec l'assemblage.

C'est une question ancienne qui revient de temps en temps et vous obtenez les mêmes réponses, pour la plupart mal informées. S'il n'y avait pas de portabilité, je ferais tout de même moi-même en assemblage. Même alors, je code en C presque comme je l'ai fait en assembleur.


1
+1 mentionnant des personnes sans aucune expérience asm, et un autre +1 devrait pour "coder en C comme asm". Lorsque j'écris des applications C ++ (oui, CPP, pas C) pour les applications intégrées, je code comme si c'était asm, par exemple en n'utilisant pas de nouveau / malloc ().
ern0

Vous utilisez donc beaucoup de choses comme char buf [MAX_PATH] qui tombe ensuite lorsque quelqu'un a des données de taille MAX_PATH + n? ;)
paulm

1
@paulm - Vous voulez dire tout comme C le fait?
Rob

1
J'espère que les auteurs assembleurs n'évitent pas l'utilisation de malloc (). Oui, sur l'embarqué, vous êtes limité en mémoire. Mais faites-le sur Unix ou un autre bureau (ou même la plupart des systèmes d'exploitation mobiles) et vous vous limitez simplement inutilement et vos utilisateurs. Aussi: moins vous écrivez de LOC, moins vous risquez d’erreur, ce qui signifie que le code de niveau supérieur aura probablement moins d’erreurs que de code inférieur.
uliwitness

1
Je viens de regarder parce que j'étais suspicieux et, oui, je peux dire que les rédacteurs et les HNers sont ici.
Rob
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.