web-dev-qa-db-fra.com

Des ressources pour apprendre à programmer en code machine?

Je suis un étudiant, novice dans la programmation et l'aimant, de Java vers C++ et vers le bas pour C. J'ai reculé vers les barebones et j'ai pensé aller plus loin vers Assembly.

Mais, à ma grande surprise, beaucoup de gens ont dit que ce n'était pas aussi rapide que C et que cela ne servait à rien. Ils ont suggéré d'apprendre à programmer un noyau ou à écrire un compilateur C. Mon rêve est d'apprendre à programmer en binaire (code machine) ou peut-être à programmer du métal nu (programmer physiquement le micro-contrôleur) ou à écrire des bios ou des chargeurs de démarrage ou quelque chose de ce genre.

La seule chose possible que j'ai entendue après tant de recherches est qu'un éditeur hexadécimal est la chose la plus proche du langage machine que j'ai pu trouver à cette époque et à cette époque. Y a-t-il d'autres choses que je ne connais pas? Existe-t-il des ressources pour apprendre à programmer en code machine? De préférence sur un micro-contrôleur/microprocesseur 8 bits.

Cette question est similaire à la mienne, mais je m'intéresse d'abord à l'apprentissage pratique, puis à la compréhension de la théorie.

25
AceofSpades

Les gens ne programment pas en code machine (sauf s'ils sont masochistes). Ils utilisent (ou développent) des outils pour générer du code machine (compilateur ou assembleur, y compris des outils de développement croisé), ou peut-être des bibliothèques générant du code machine (LLVM, libjit, GNU lightning, .... Les ressources sur la génération, la compilation, les optimiseurs et les micro-architectures de code machine sont également pertinentes.

Et très souvent, un bon compilateur d'optimisation génère un meilleur code machine que vous ne pourriez le faire. Vous ne pourrez probablement pas écrire un code assembleur de 200 lignes mieux qu'un bon optimiseur.

Si vous voulez comprendre le code machine, apprenez d'abord l'assemblage. Il est très proche du code machine. Utilisez-le à bon escient, uniquement pour les choses que vous ne pouvez pas coder en C (ou dans un langage de niveau supérieur, comme Ocaml, Haskell, Common LISP, Scala). Un bon moyen est souvent d'utiliser des instructions asm (notamment GCC Extended Assembly feature) à l'intérieur d'une fonction C. Lecture du code d'assemblage (généré par gcc -S -O2 -fverbose-asm) peut également être utile.

Le Linux Assembly HowTo est une bonne chose à lire.

L'architecture du jeu d'instructions du processeur actuel (c'est-à-dire le jeu d'instructions compris par la puce) est assez complexe. Les plus courants sont x86 (un PC typique en mode 32 bits), X86-64 (un PC de bureau en mode 64 bits), ARM (smartphones, ...), PowerPC etc. Ils sont tous assez complexes (pour des raisons historiques et économiques). Peut-être apprendre d'abord un ensemble d'instructions hypothétiques comme par exemple MMIX de Knuth est plus simple.

27

Comme indiqué précédemment Learn Assembly .

Un langage d'assemblage est un langage de programmation de bas niveau pour les ordinateurs, microprocesseurs, microcontrôleurs et autres appareils programmables. Il implémente une représentation symbolique des codes machine et autres constantes nécessaires pour programmer une architecture CPU donnée.

L'assemblage est donc un symbolic representation of machine code.

Vous demandez peut-être maintenant "Ok, alors comment puis-je apprendre tout cela?" Je suis tellement content que vous ayez demandé:

  1. Comprenez ce que c'est. C'est très bas niveau et vous donnera une compréhension très approfondie d'un ordinateur. Vous voudrez peut-être commencer par Wikipedia puis lire ce court passage .
  2. Apprenez-le! Les meilleures lectures sont probablement The Art of Assembly Language et Assembly Language étape par étape: Programmation avec Linux
  3. Obtenez le codage!
13
Dynamic

Je vous suggère fortement de reconsidérer votre objectif et voici pourquoi:

J'ai d'abord appris le langage d'assemblage 6502 sur le micro-ordinateur BBC (modèle B, 32K). Il avait une implémentation BASIC impressionnante qui comprenait un assembleur de macros. Nous les avions à l'école, alors j'ai écrit toutes sortes de programmes espiègles qui feraient des choses comme la manipulation directe du tampon d'écran pour faire un Lemming marcher sur chaque écran, autour de la pièce (ils étaient en réseau) si les machines n'avaient pas été utilisées pendant 10 minutes . Cela a provoqué des crises de rires chez mes amis de la 7e année.

Quand j'ai eu un Commodore 64 à la maison, j'ai appris qu'il avait un processeur 6510 qui exécutait également le langage d'assemblage 6502 mais avec quelques extras intéressants. J'ai dû acheter un assembleur (venu sur une cartouche) et appeler les programmes via BASIC. Avec de grandes visions d'écrire un jeu à succès, j'ai finalement réussi à créer plusieurs démos que le matériel d'affichage vidéo twiddled enregistre sur interruption pour faire des effets de barre de couleur intéressants qui s'animaient à la musique à puce funky. Impressionnant, mais pas très utile.

J'ai ensuite obtenu un Acorn Archimedes A310 qui avait un processeur ARM2, j'ai donc utilisé la même implémentation géniale BASIC avec un assembleur de macros intégré que le BBC Micro (même héritage). J'ai réussi à assembler quelques jeux pour lesquels un ami arty a fourni des graphiques, ainsi que des démos trippy à base de sinusoïdes. Les deux étaient difficiles à programmer et un mauvais code pouvait détruire la machine (déclencher accidentellement le registre de réinitialisation matérielle, etc.), tout perdre si je n'avais pas enregistré (sur disquette!).

À l'université, j'ai été initié au C++ et donc au C. J'ai pu l'utiliser pour programmer Sun/Solaris et d'autres gros ordinateurs centraux. Je n'ai aucune idée des architectures CPU sur lesquelles ces machines fonctionnaient - je n'ai jamais eu besoin d'utiliser l'assembleur ou de lire le code machine car les outils C++ m'ont donné la puissance dont j'avais besoin pour produire des applications professionnelles.

Après Uni, j'ai travaillé sur Windows et plusieurs versions d'Unix. C et C++ ont travaillé sur toutes ces machines et finalement Java l'a fait aussi.

J'ai ensuite travaillé sur Windows et Dreamcast en utilisant C++ avec DirectX avec une chaîne d'outils complète pour le débogage.

J'ai ensuite pris un travail en travaillant avec des chipsets ARM pour Smart TV (en 2000). Bien que mon expérience avec ARM2 ait pu être pertinente ici, le travail était basé sur C. J'ai trouvé que tous les fouilles avec le matériel que j'avais faites sur Archimède pouvaient également être faites en C en utilisant des opérations de twiddling simples. Une partie de mon rôle consistait à migrer la base de code vers Windows, PlayStation 2, Linux, d'autres jeux de puces TV et mobiles. Toutes ces plates-formes étaient disponibles avec un compilateur C (souvent GCC) et un certain niveau d'API pour écrire sur la machine sous-jacente - le monde intégré est rarement un noyau O/S. Je n'ai jamais eu besoin de connaître le code machine complet pour une plate-forme particulière au-delà de l'écriture d'un chargeur de démarrage et d'un mini-BIOS, qui ont tous deux sauté dans le code C à la première occasion disponible (après avoir configuré des vecteurs de déroutement, garantissant l'endianité et mode instruction et établissement d'une pile).

Le travail suivant consistait à travailler avec C++, C # et JavaScript sur Windows. Pas de code machine.

Le travail actuel fonctionne avec C++, JavaScript, Python, LUA, HTML et d'autres langages sur diverses plates-formes. Je n'ai aucune idée du code machine que ces plateformes exécutent, et je n'ai pas besoin de le savoir - le compilateur traduit notre code en ce qu'il doit être. S'il se bloque, j'attrape l'erreur dans un débogueur ou via des diagnostics d'exécution (exceptions, signaux, etc.).

Pour le plaisir, je développe des applications iOS sur le peu de temps libre que j'ai à la maison. Il utilise Objective-C et une API qui fonctionne sur plusieurs chipsets. Apparemment, ils sont basés sur ARM, mais je n'ai jamais vu de code machine dans mon développement.

Bien que ce soit un exercice fascinant pour apprendre le langage d'assemblage, il existe maintenant des outils et des langages de niveau supérieur qui vous permettent d'être d'un ordre de grandeur (ou deux) plus productifs.

Le nombre de possibilités d'emploi disponibles pour un incroyable programmeur de langage d'assemblage/code machine est minuscule par rapport à quelque chose comme JavaScript, Java, C #, C++ ou ObjC.

Je vous conseillerais d'en faire un hobby/intérêt secondaire plutôt qu'un objectif principal.

8
JBRWilkinson

Ma suggestion? Apprenez MIPS et apprenez à construire un (simple) processeur MIPS. C'est en fait plus facile qu'il n'y paraît.

L'avantage de MIPS par rapport à certaines des autres architectures est la simplicité. Vous ne serez pas pris dans une tonne de petits détails, mais vous apprendrez toujours toutes les grandes idées dont vous avez besoin pour écrire du code dans d'autres architectures.

Par coïncidence, c'était le projet final pour ma (troisième) classe d'introduction CS. Si vous le souhaitez, vous pouvez lire le devoir et parcourir les conférences sous la forme vidéos ou diapositives .

Entre autres choses, nous avons couvert comment le code MIPS est transformé en binaire; nous avons même dû décoder du code machine (très simple) lors des examens.

Même si vous ne voulez pas tout couvrir, la plupart des conférences ont été données par l'un des professeurs préférés des étudiants et sont amusantes à regarder par elles-mêmes.

6
Tikhon Jelvis

Je suis un étudiant, novice dans la programmation et l'aimant, de Java vers C++ et vers le bas pour C. J'ai reculé vers les barebones et j'ai pensé aller plus loin vers Assembly.

Excellent chemin à parcourir. Mon saut (automne?) De C à l'Assemblée et plus bas était un cours universitaire Organisation et conception informatique , basé sur le livre du même nom.

Je recommande vivement ce livre pour les premiers chapitres sur l'assemblage MIPS de base, tout au long du pipelining et de l'architecture de la mémoire. Encore mieux serait de suivre un cours sur le même thème ou de trouver des conférences en ligne.

Voir aussi le MARS MIPS Simulator pour vous salir les mains en écrivant l'assemblage.

6
Matt Stephenson

Si vous voulez comprendre comment fonctionne complètement la machine, pourquoi ne pas aller au niveau le plus bas possible et vous frayer un chemin jusqu'à l'endroit où vous vous trouvez (par exemple, C, C++)?

J'entends par là: pourquoi ne construisez-vous pas votre propre additionneur 4 bits avec des transistors sur un circuit (recherchez simplement Google si vous recherchez des instructions/un didacticiel)?

Après cela, construisez un petit ordinateur avec de la RAM, puis commencez à apprendre Assembly et écrivez un ou deux programmes avec.

4
Daniel Scocco

Code de Charles Petzold est une très bonne introduction au sujet et décrit le processus de construction d'un ordinateur, y compris comment construire des additionneurs, des compteurs et RAM tableaux et introduit le code machine) et le langage d'assemblage et leur relation avec les langages de niveau supérieur. C'est aussi une excellente lecture de l'histoire de l'informatique.

Et je viens de lire cette question sur electronics.stackexchange qui pourrait aussi être utile

1
br3w5

J'ai un jeu d'instructions qui a été fait pour cela, un simulateur et quelques tutoriels sur les bases d'une instruction ou d'un concept par leçon. Tapez simplement le programme, exécutez-le, puis apprenez ce qu'il fait, passez à la leçon suivante.

http://www.github.com/dwelch67/lsasim

J'ai également des simulateurs pour quelques ensembles d'instructions grand public. Tout ou partie d'entre eux sont bons pour utiliser pour apprendre asm (si vous sentez vraiment que vous devez apprendre x86, apprenez-le en dernier et utilisez un simulateur comme celui que j'ai bifurqué, 8088/86 d'abord puis avancez). Apprendre contre un simulateur a des avantages et des inconvénients, un pro majeur, surtout au début, c'est que vous ne plantez rien et que vous avez une grande visibilité. Sauter tête première dans une plate-forme intégrée, un microcontrôleur, etc. pour apprendre un nouvel ensemble d'instructions, vous devez surmonter les obstacles de ne pas pouvoir voir ce qui se passe, ce qui conduit à une longue liste de façons d'échouer ...

1
old_timer