Je programme dans des langages de niveaux supérieurs (Python, C #, VBA, VB.NET) depuis environ 10 ans et je ne comprends absolument rien à ce qui se passe "sous le capot".
Je me demande quels sont les avantages d'apprendre l'assemblage, et comment cela m'aidera-t-il en tant que programmeur? Pouvez-vous s'il vous plaît me fournir une ressource qui me montrera exactement le lien entre ce que j'écris dans un code de niveau supérieur et ce qui se passe dans l'assembly?
for
boucle en déclarant des variables en dehors de celle-ci. exempleRéponses:
Parce que vous comprendrez comment cela fonctionne vraiment .
En gros, tout ce que nous écrivons en C # ou en Python doit être traduit en une séquence d'actions de base pouvant être exécutées par un ordinateur. Il est facile de penser à un ordinateur en termes de classes, de génériques et de compréhension de liste, mais ceux-ci n'existent que dans nos langages de programmation de haut niveau.
Nous pouvons penser à des constructions de langage qui ont l'air vraiment sympa mais qui ne se traduisent pas très bien en une manière de faire des choses de bas niveau. En sachant comment cela fonctionne réellement, vous comprendrez mieux pourquoi les choses fonctionnent comme elles le font.
la source
Cela vous donnera une meilleure compréhension de ce qui se passe "sous le capot" et du fonctionnement des pointeurs, ainsi que de la signification des variables et de l'architecture des registres (allocation et gestion de la mémoire, passage de paramètres (par valeur / par référence), etc.) en général.
Pour un coup d'œil rapide avec C, comment ça se passe?
compiler avec
gcc -S so.c
et jeter un coup d'œil à la sortie de l'assembly dansso.s
:la source
so.c
fichier standard pour les questions stackoverflow (comme moiso.py
,so.awk
etc.) pour tester les choses rapidement. So.S .. :)gcc -O -c -g -Wa,-ahl=so.s so.c
vous pouvez voir la sortie de l'assembly pour chaque ligne de code C. Cela rend un peu plus facile de comprendre ce qui se passe.5:so.c
le code de la ligne 5 deso.c
.Je pense que la réponse que vous cherchez est ici: http://www.codeproject.com/Articles/89460/Why-Learn-Assembly-Language
Une citation de l'article:
En outre, je recommanderais ce livre car il contient une version simplifiée de l’architecture informatique: Introduction aux systèmes informatiques: de Bits et Gates à C et au-delà, 2 / e Yale N. Patt, Université du Texas à Austin Sanjay J. Patel, Université de l'Illinois à Urbana / Champaign
la source
À mon humble avis, cela n’aide pas beaucoup.
Je connaissais très bien l’assemblage x86. Cela a aidé un peu lorsque l'assemblage est apparu dans mes cours, lors d'une interview, et cela m'a aidé à prouver qu'un compilateur (Metrowerks) générait un code incorrect. C'est fascinant de voir le fonctionnement de l'ordinateur et je me sens intellectuellement plus riche de l'avoir appris. C'était aussi très amusant de jouer avec à l'époque.
Cependant, les compilateurs actuels sont mieux à même de générer un assemblage que quiconque sur presque n'importe quel élément de code. À moins d'écrire un compilateur ou de vérifier que votre compilateur fait la bonne chose, vous perdez probablement votre temps à l'apprendre.
J'admets que beaucoup de questions que les programmeurs C ++ posent encore utilement sont éclairées par la connaissance de l'assemblage. Par exemple: devrais-je utiliser des variables de pile ou de tas? dois-je passer par valeur ou par référence const? Cependant, dans presque tous les cas, j'estime que ces choix devraient être basés sur la lisibilité du code plutôt que sur des gains de temps de calcul. (Par exemple, utilisez des variables de pile chaque fois que vous souhaitez limiter une variable à une portée.)
Mon humble suggestion est de mettre l'accent sur les compétences qui comptent vraiment: la conception de logiciels, l'analyse d'algorithmes et la résolution de problèmes. Avec l'expérience acquise dans le développement de grands projets, votre intuition va s'améliorer, ce qui augmente votre valeur bien plus que de savoir assembler (à mon avis).
la source
Vous devez être familiarisé avec un niveau "plus profond" du système sur lequel vous travaillez. Sauter trop bas d’un coup n’est pas mauvais, mais peut ne pas être aussi utile qu’on le souhaiterait.
Un programmeur dans une langue de haut niveau devrait apprendre une langue de niveau inférieur (C est une excellente option). Vous n'avez pas besoin d'aller jusqu'au montage pour avoir une idée de ce qui se passe sous les couvertures lorsque vous demandez à l'ordinateur d'instancier un objet, ou de créer une table de hachage ou un ensemble - mais vous devriez être capable de coder leur.
Pour un programmeur java, apprendre un peu de C vous aiderait dans la gestion de la mémoire, en passant des arguments. Écrire une partie de la vaste bibliothèque java en C aiderait beaucoup à comprendre quand utiliser quelle implémentation de Set (voulez-vous un hachage? Ou un arbre?). Traiter avec char * dans un environnement threadé aidera à comprendre pourquoi String est immuable.
Passé au niveau suivant ... Les programmeurs en CA devraient être familiarisés avec l'assemblage, et les types d'assemblages (que l'on trouve souvent dans les magasins de systèmes intégrés) feraient bien de bien comprendre les choses au niveau des portes. Ceux qui travaillent avec des portes devraient connaître quelques notions de physique quantique. Et ces physiciens quantiques, eh bien, ils essaient encore de déterminer quelle est la prochaine abstraction.
la source
Puisque vous n'avez pas mentionné C ou C ++ dans les langages que vous connaissez. Je recommanderais FORTEMENT de bien les apprendre avant même de penser à l’assemblage. C ou C ++ vous donnera tous les concepts de base totalement transparents dans les langages gérés et vous comprendrez la plupart des concepts mentionnés dans cette page avec l’un des langages les plus importants que vous pouvez utiliser dans des projets réels. C'est une réelle valeur ajoutée à vos compétences en programmation. Sachez que l’assemblage est utilisé dans des domaines très spécifiques et qu’il n’est pas aussi utile que C ou C ++.
J'irais même plus loin en disant qu'il ne faut pas plonger dans l'assemblage avant de comprendre comment fonctionnent les langues non gérées. C'est presque une lecture obligatoire.
Vous devriez apprendre le montage si vous voulez aller encore plus bas. Vous voulez savoir exactement comment chaque construction du langage est créée. C'est informatif mais c'est une complexité de niveau très différente.
la source
Si vous connaissez bien une langue, vous devez avoir au moins une connaissance de base de la technologie avec un niveau d'abstraction inférieur.
Pourquoi? Lorsque les choses tournent mal, la connaissance des mécanismes sous-jacents facilite beaucoup le débogage de problèmes étranges et l'écriture naturelle d'un code plus efficace.
En utilisant Python (/ CPython) comme exemple, si vous commencez à avoir des plantages bizarres ou des performances médiocres, il peut être très utile de savoir comment déboguer le code C, tout comme sa méthode de gestion de la mémoire de décompte. Cela vous aiderait également à savoir quand / si écrire quelque chose comme une extension C, et ainsi de suite ...
Pour répondre à votre question dans ce cas, la connaissance de l'assemblage n'aiderait vraiment pas un développeur Python expérimenté (il y a trop d'étapes d'abstraction - toute opération effectuée en Python donnerait lieu à de nombreuses instructions d'assemblage).
..mais si vous êtes expérimenté avec C, il serait utile de connaître "le niveau suivant" (assemblage).
De même, si vous utilisez CoffeScript, il est (très) utile de connaître le langage Javascript. Si vous utilisez Clojure, la connaissance de Java / JVM est utile.
Cette idée fonctionne également en dehors des langages de programmation - si vous utilisez Assembly, il est judicieux de vous familiariser avec le fonctionnement du matériel sous-jacent. Si vous êtes un concepteur Web, il est judicieux de savoir comment l’application Web est mise en œuvre. Si vous êtes un mécanicien automobile, c'est une bonne idée d'avoir quelques connaissances en physique.
la source
Ecrivez un petit programme c et démontez la sortie. C'est tout. Cependant, soyez prêt pour un degré plus ou moins grand de "code de gestion" ajouté au profit du système d'exploitation.
Assembly vous aide à comprendre ce qui se passe sous le capot, car il traite directement de la mémoire, des registres de processeurs, etc.
Si vous voulez vraiment utiliser du métal nu sans toute la complexité d’un système d’exploitation, essayez de programmer un Arduino en langage assembleur.
la source
Il n'y a pas de réponse définitive, car les programmeurs ne sont pas tous d'un type. Avez-vous besoin de savoir ce qui se cache en dessous? Si oui, alors apprenez-le. voulez-vous simplement l'apprendre, par curiosité? Si oui, alors apprenez-le. Si cela ne vous apporte aucun avantage concret, alors pourquoi s'en préoccuper? Faut-il avoir le niveau de connaissances d'un mécanicien pour conduire une voiture? Un mécanicien a-t-il besoin du niveau de connaissances d'un ingénieur, juste pour travailler sur une voiture? C'est une analogie sérieuse. Un mécanicien peut être un très bon mécanicien productif sans plongeur pour approfondir sa connaissance des véhicules qu’il entretient. Pareil pour la musique. Est-ce que vous êtes vraiment dans la complexité de la mélodie, de l'harmonie et du rythme pour être un bon chanteur ou un bon joueur? Non. Certains musiciens exceptionnellement talentueux ne peuvent pas lire une partition, encore moins vous dire la différence entre les modes Dorian et Lydian. Si vous voulez, d'accord, mais non, vous n'en avez pas besoin. Si vous êtes un développeur Web, l’assemblage n’a aucune utilité pratique à laquelle je puisse penser. Si vous êtes dans des systèmes embarqués ou quelque chose de vraiment spécial, cela peut être nécessaire, mais si c'était le cas, vous le sauriez.
Voici la position de Joel sur cette valeur consistant à apprendre un langage de bas niveau: http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html
la source
En fait, ce qui serait probablement mieux pour vous serait une classe qui n’existe nulle part (à ma connaissance): c’est une classe qui combine un bref aperçu du langage machine / assembleur et des concepts d’adressage de stockage avec une visite guidée de la construction du compilateur. , génération de code et environnements d'exécution.
Le problème est qu’avec un langage de haut niveau, loin du matériel, comme C # ou Python, vous n’appréciez pas vraiment le fait que chaque mouvement que vous effectuez se transforme en centaines, voire en milliers, d’instructions machine. 't ont tendance à comprendre comment quelques lignes d'un langage de haut niveau peuvent provoquer l'accès à de grandes quantités de stockage et leur modification. Ce n'est pas tant que vous ayez besoin de savoir précisément ce qui se passe "sous les couvertures", mais vous devez avoir une idée de l'ampleur de ce qui se passe et d'une conception générale du type de choses qui se produisent.
la source
Ma réponse à cette question a évolué relativement récemment. Les réponses existantes couvrent ce que j'aurais dit dans le passé. En fait, cela reste couvert par la réponse principale - le point "apprécier les concepts de la programmation de niveau supérieur", mais c'est un cas spécial qui, à mon avis, mérite d'être mentionné ...
Selon ce billet de blog de Jeff Atwood , qui fait référence à une étude, comprendre la cession est un élément clé de la compréhension de la programmation. Les programmeurs apprenants comprennent soit que la notation ne représente que les étapes suivies par l'ordinateur et les justifie, ou encore se confondre perpétuellement par des analogies trompeuses avec des équations mathématiques, etc.
Eh bien, si vous comprenez ce qui suit à partir de 6502 assembleur ...
C'est vraiment juste les étapes. Ensuite, lorsque vous apprenez à traduire cela en une déclaration de mission ...
Vous n'avez pas besoin d'une analogie trompeuse avec une équation mathématique - vous avez déjà un modèle mental correct pour le mapper.
EDIT - bien sûr, si l’explication que vous obtenez
LDA variable
est essentiellementACCUMULATOR = variable
, et c’est exactement ce que vous obtenez à partir de certains tutoriels et références, vous retrouvez votre point de départ et ce n’est pas une aide du tout.J'ai appris 6502 assembler comme deuxième langue, la première étant Commodore Basic, et je n'avais pas vraiment appris grand-chose à l'époque - en partie parce qu'il y avait si peu à apprendre, mais aussi parce que l'assembleur semblait tellement plus intéressant à l'époque . En partie à l'époque, en partie parce que j'étais un geek de 14 ans.
Je ne recommande pas de faire ce que j'ai fait, mais je me demande si l'étude de quelques exemples très simples dans un langage d'assembleur très simple pourrait constituer un préalable utile à l'apprentissage de langages de niveau supérieur.
la source
Sauf si vous êtes un rédacteur de compilateur ou si vous avez besoin de quelque chose de hautement optimisé (tel qu'un algorithme de traitement de données), l'apprentissage du codage d'assembleurs ne vous apportera aucun avantage.
Écrire et maintenir du code écrit en assembleur est très difficile. Par conséquent, même si vous connaissez très bien le langage assembleur, vous ne devriez pas l'utiliser, à moins qu'il n'y ait pas d'autre moyen.
L'article " Optimisation pour SSE: une étude de cas " montre ce qu'il est possible de faire si vous passez à l'assemblage. L'auteur a réussi à optimiser l'algorithme de 100 cycles / vecteur à 17 cycles / vecteur.
la source
Écrire en assembleur ne vous donnerait pas une augmentation magique de la vitesse, car en raison de la quantité de détails (allocation de registre, etc.), vous écrirez probablement l'algorithme le plus trivial de tous les temps.
De plus, avec les processeurs modernes (conçus après 70-80), l’assemblage des processeurs ne vous donnera pas un nombre suffisant de détails pour savoir ce qui se passe (c’est-à-dire sur la plupart des processeurs). Les PU modernes (CPU et GPU) sont assez complexes en ce qui concerne les instructions de planification. Connaître les bases de l'assemblage (ou pseudo-assemblage) permettra de comprendre les manuels / cours d'architecture informatique qui fourniraient des connaissances supplémentaires (caches, exécution dans le désordre, MMU, etc.). Habituellement, vous n'avez pas besoin de connaître les ISA complexes pour les comprendre (MIPS 5 est un IIRC très populaire).
Pourquoi comprendre le processeur? Cela pourrait vous donner beaucoup plus de compréhension de ce qui se passe. Supposons que vous écrivez la multiplication matricielle de manière naïve:
Il peut être «assez bon» pour votre objectif (si c'est une matrice 4x4, il pourrait être compilé en instructions vectorielles de toute façon). Cependant, il existe des programmes très importants lorsque vous compilez des tableaux massifs - comment les optimiser? Si vous écrivez le code en assembleur, vous obtiendrez peut-être quelques améliorations (à moins que vous ne fassiez comme la plupart des gens - également de manière naïve, sous-utiliser les registres, charger / stocker en mémoire en permanence et avoir un programme plus lent que dans le langage HL) .
Cependant, vous pouvez inverser les lignes et gagner magiquement de la performance (pourquoi? Je le laisse comme «devoir») - IIRC en fonction de divers facteurs pour les grandes matrices, il peut même être 10x.
Ceci dit - des compilateurs sont en mesure de le faire ( graphite pour gcc et Polly pour tout ce qui utilise LLVM). Ils sont même capables de le transformer en (désolé - j'écris en bloquant de mémoire):
Pour résumer, connaître les bases d'un assemblage vous permet d'explorer divers «détails» de la conception du processeur, ce qui vous permettrait d'écrire des programmes plus rapidement. Il peut être intéressant de connaître les différences entre les architectures RISC / CISC ou VLIW / processeur vectoriel / SIMD / .... Cependant, je ne commencerais pas avec x86 car ils ont tendance à être assez compliqués (peut-être aussi avec ARM) - savoir ce qu’est un registre, etc.
la source
Normalement, c'est TRES important pour le débogage. Que faites-vous lorsque le système s’arrête au milieu d’une instruction et que l’erreur n’a aucun sens? Le problème des langages .NET est bien moins grave tant que vous utilisez uniquement du code sécurisé: le système vous protégera presque toujours de ce qui se passe sous le capot.
la source
En bref, je pense que la réponse est parce que vous pouvez faire plus si vous apprenez le montage. Learning Assembly permet d'accéder aux domaines de la programmation de périphériques intégrés, de la pénétration de la sécurité et du contournement, du reverse engineering et de la programmation système, dans lesquels il est très difficile de travailler si vous ne connaissez pas l'assembleur.
Quant à apprendre à améliorer les performances d'un programme, cela est douteux dans la programmation d'applications. La plupart du temps, il y a tant de choses sur lesquelles se concentrer avant d’atteindre ce niveau d’optimisation, comme optimiser l’accès des entrées / sorties sur disque et sur le réseau, optimiser la construction de l’interface graphique, choisir les algorithmes appropriés, maximiser tous les cœurs. , fonctionnant sur le meilleur matériel que l’argent peut acheter et passant de l’interprétation au langage compilé. Sauf si vous créez un logiciel destiné à d'autres utilisateurs finaux, le matériel est économique, comparé au salaire horaire d'un programmeur, notamment avec la disponibilité du cloud.
En outre, vous devez peser la vitesse d'exécution du programme et la lisibilité de votre code après avoir été heurté par un bus, arrêté ou être revenu à la base de code pour le modifier un an après la rédaction de la dernière version.
la source
Je recommanderais l'apprentissage d'algorithmes: tri, listes chaînées, arbres binaires, hachage, etc.
Voir aussi Structure et interprétation des programmes informatiques groups.csail.mit.edu/mac/classes/6.001/abelson-sussman-lectures. Ce cours vidéo vous apprendra tout ce que vous devez savoir, y compris les algorithmes (comment tout faire quelques commandes primitives, une primitive lisp et des assembleurs provocants).
Enfin, si vous devez apprendre à assembler, découvrez-en un facile comme ARM (il est également utilisé dans environ 4 fois plus de périphériques que x86).
la source
Eh bien, la réponse est que tout simplement parce que le langage que vous utilisez doit être interprété ou compilé dans assembleur à la fin. Peu importe la langue ou la machine.
La conception des langues découle du fonctionnement de la CPU. Plus sur les programmes de bas niveau, moins sur les programmes de haut niveau.
Je terminerai en disant que ce n'est pas seulement que vous devez connaître peu d'assembleur, mais l'architecture du processeur, que vous apprendrez en apprenant l'assembleur.
Quelques exemples: Il y a beaucoup de programmeurs java qui ne comprennent pas pourquoi cela ne fonctionne pas, et encore moins de savoir ce qui se passe lorsque vous l'exécutez.
Si vous connaissez un petit assembleur, vous saurez toujours que le contenu d'un emplacement de mémoire n'est pas identique au nombre indiqué dans la variable de pointeur qui "pointe" vers cet emplacement.
Pire encore, même dans les livres publiés, vous lirez quelque chose comme dans JAVA. Les primitives sont passées par valeur et les objets par référence, ce qui est complètement incorrect. Tous les arguments en Java sont passés par valeur et Java ne peut PAS transmettre d'objets à des fonctions, mais uniquement des pointeurs qui sont passés par valeur.
Si vous assemblez maintenant ce qui se passe, c’est évident, sinon c’est si compliqué à expliquer que la plupart des auteurs vous mentent.
Bien sûr, leurs ramifications sont subtiles mais peuvent vous causer de vrais problèmes plus tard. Si vous connaissez l'assembleur, cela ne pose pas de problème, sinon, vous passerez une longue nuit au débogage.
la source
String a = "X"; String b = "X"; if( a==b) return true;
ce que fait en fait à== true
cause de quelque chose appeléString interning
que le compilateur fait. Toutes les autres déclarations Java sont également fausses. Java n'a pas de pointeurs, il a des références qui ne sont pas la même chose. Et rien de tout cela n'a rien à voir avec l'assembleur. Java transmet les primitives par valeur ainsi que les références par valeur. Java n'a pas de pointeurs, il ne peut donc pas les ignorer. Encore une fois, tous ne sont pas pertinents pour connaître ASM.