Débuter avec l'ASM

a marqué ce sujet comme résolu.

Bonjour :) ,

J'ai vu que la NASA avait publié le code source d'Apollon 11, qui est en assembleur.

Je me suis donc dit, pourquoi ne pas apprendre ce langage ?

J'ai donc voulu commencer, mais j'avais vu qu'il existait plusieurs versions de l'ASM et ont m'a conseillé le NASM parce qu'il était multi-plateforme. Après des recherches, j'ai trouvé un tuto sur Developpez.

J'en suis au chapitre sur la gestions des entrées au clavier, mais j'ai déjà une première question: Est-ce que j'ai bien fait de commencer à apprendre cette version d'ASM ?

Et ensuite, Windows 10 ne veut pas lancer les fichiers .com, je suis obligé d'utiliser un "émulateur" de DOS, si j'ai bien compris parce que ce type de fichier fonctionne seulement sur DOS.
Mais du coup, comment faire pour générer un éxécutable ? Il faut peut-être que j'attende d'être plus avancé en NASM ?

Merci d'avance,
Ardakaniz

Salut,

En version courte, les tutos et bouquins que tu trouveras sur Internet pour apprendre l’assembleur sont à chier. Entre autres, parce qu’ils commencent systématiquement par l’assembleur 16 bits, qui est obsolète depuis 20 ans. C’est ce qui explique que ton .COM ne marche pas.

Il va falloir que je remette en ligne mon début de cours d’assembleur…

La version plus longue en EDIT.

EDIT : comme pour le Seigneur des Anneaux, la version longue…

Basiquement, l’assembleur n’est rien d’autre que le code machine retranscrit sous une forme compréhensible par un humain. Il existe donc une forme d’assembleur par famille de processeurs, et elles sont incompatibles entre elles : par exemple, le tuto que tu as commencé à lire ne te permettra pas de comprendre l’assembleur utilisé par Apollo, parce que ce ne sont pas les mêmes bébêtes en-dessous.

Parmi les cours d’assembleur que tu pourras trouver, il n’y aura grosso modo que trois familles de processeurs.

  • L’assembleur MIPS, réputé pour être assez basique, mais qui nécessite un matos pas si courant et largement obsolète pour pouvoir être testé.
  • L’assembleur ARM (pour les processeurs qu’on trouve généralement dans les téléphones, tablettes, dans le RPi, ou dans certaines consoles de poche), pour lequel il existe à ma connaissance un unique cours sur Internet, incomplet.
  • L’assembleur x86 (pour les processeurs que l’on trouve dans la quasi-totalité des Mac et PC de ces 15 dernières années), qui lui représente la quasi-totalité des cours d’assembleur en ligne et en livres, entre autres parce que c’est le plus facile à tester.

Mais cela ne s’arrête pas là. Coder en assembleur pur, c’est la croix et la bannière, essentiellement à cause des instructions de saut. On utilise donc presque toujours des sur-ensembles de l’assembleur pur, qui aident à programmer plus facilement : il en existe un par logiciel d’assemblage, et pour la famille x86, tu auras ainsi l’assembleur FASM, l’assembleur gas, l’assembleur TASM, MASM, NASM, YASM…

À titre personnel, je préfère la variante NASM, mais c’est une pure affaire de goût.

Enfin, les processeurs évoluant avec le temps, au sein d’une même famille d’assembleur, il en existe plusieurs générations. Par exemple, l’assembleur ARM connaît pas moins de 8 versions à l’heure actuelle, dont seules les versions 4, 6 et 7 sont réellement d’usage courant.

Pour la famille x86, il s’agit du mode réel (ou 16 bits), du mode protégé (ou 32 bits) et du mode long (ou 64 bits). Le mode protégé existe depuis 1986, et on peut considérer que le mode réel est largement obsolète depuis 1995 environ. Pourtant, la très grande majorité des cours d’assembleur x86 que tu trouveras commencent par le mode réel, et bien souvent, ne vont pas plus loin. D’où mon jugement sévère de tout à l’heure…

Il y a une dernière difficulté. Les systèmes d’exploitation ont leur propre format d’exécutables : ELF sous les Unix, PE sous Windows, etc. qui contiennent bien plus de choses que le seul code machine traduit depuis l’assembleur. Et un code machine brut ne fonctionnera généralement pas, surtout s’il est en assembleur 16 bits.

+7 -0

En plus du message de Dominus, j'ajouterai que la plus grande difficulté des cours sur le langage d'assemblage est qu'il est appris tel quel sans précision sur le fonctionnement d'un processeur et de la mémoire. Ceci est fort dommage si l'on souhaite comprendre le tas ou la pile.

Il y a un super livre qui permet de construire son ordinateur à partir de zéro qui montre comment construire son processeur, puis comment programmer en assembleur sur ce processeur (les cinq premiers chapitres). Ce livre s'appelle The Elements of Computing Systems. Tu peux trouver un PDF de ce livre assez facilement en ligne, sinon MP-moi.

Après il faut avouer que le MIPS a été crée entre autre dans un but pédagogique, afin d'avoir une architecture simple, même si aujourd'hui, certains choix du passé font qu'il contient quelques complications (cependant vis à vis du x86 ce n'est rien). Et donc, il sera plus facile pour toi de trouver des ressources pédagogiques de MIPS (enfin des supports de cours avec TD/TP).

Même si ton ordinateur n'est pas un x86 et donc que tu ne peux exécuter ton programme directement sur le processeur de ta machine, il existe des simulateurs MIPS comme (mars) qui font très bien le travail.

Les ARM ne seraient ils pas une bonne cible pour ce genre de cours ? C'est une évolution des MIPS qui ont pour moi l'avantage d'être infiniment plus simple que les x86 et qu'on peut facilement tester sur du matériel réel (un RPi par exemple).

Si, par certains aspects, l’assembleur ARM peut être plus simple que l’assembleur x86. Après, l’accès à la mémoire est assez dégueulasse, et il y a de grosses limitations bien chiantes sur les valeurs immédiates.

Et on est vachement plus limité au niveau du choix du logiciel d’assemblage : le seul qui soit libre, qui supporte les versions récentes d’ARM et qui ne nécessite pas l’installation de Cygwin pour fonctionner, c’est le plugin ARM pour FASM.

Et il n’y a vraiment presque rien comme matériel pédagogique préexistant, donc se lancer dans la rédaction d’un tuto d’assembleur ARM récent, ça nécessite de partir de zéro.

+0 -0

J'ai une petite question pour toi Dominus, tu dit qu'en gros tout ce qu'on trouve en ligne est mauvais, cela inclus le tutoriel en beta sur OCR ? J'ai vu vite fait qu'il y en a un mais je ne l'ai pas lu parce qu'il faudrait s'inscrire.
Ou peut être qu'il s'agit de celui que tu veux remettre en ligne ? Je n'ai aucune idée de l'identité de l'auteur là bas.

Ça fait une éternité et demie que je n’ai plus de compte sur OCR, je me suis donc créé un compte poubelle1 pour aller voir. Et je confirme, le tuto en rédaction est à chier. Il souffre des mêmes défauts que les autres.

  • L’assembleur 64 bits ? Pour quoi faire ? Faisons plutôt du 16 bits… Dans son cas à lui, c’est carrément ubuesque : il explique que les systèmes d’exploitation modernes ne sont plus capables d’exécuter du code 16 bits, mais plutôt que d’enseigner l’assembleur 64 bits, il fait installer DosBox pour pouvoir émuler MS-DOS ! J’en chialerais presque…
  • Le cours commence par des tartines et des tartines d’histoire des ordinateurs, et de fonctionnement des ordinateurs, et de plein de détails sur les registres, et mon cul sur la commode, tant et si bien qu’il faut attendre la dernière section du troisième chapitre pour voir la première instruction d’assembleur. Et le quatrième pour entendre enfin parler de NASM et pouvoir compiler un bout de code.
  • Mais non, ce serait encore trop beau. On continue avec toutes les manières possibles et imaginables de déclarer des variables, et encore d’autres trucs du même acabit, et c’est seulement au septième chapitre que le cours nous gratifie enfin d’un putain de Hello World.

  1. En réalité, je me suis créé quatre comptes poubelle. Parce qu’en cherchant le sujet de la bêta du cours d’assembleur, je suis tombé sur un sujet qui fait remarquer que le cours sur RSA est pas à jour. Alors j’ai voulu leur laisser un message pour leur dire « viendez voir mon cours sur ZdS, il est plus mieux ». Mais quoi que je fasse, même en ne mettant pas de lien, mon message est systématiquement considéré comme du spam. CONNARDS !!! 

+2 -0

Salut,

@Dominus : prière de rester poli. ;)

@backmachine : il y a différentes approches pour enseigner l'Assembleur, et la plus fréquente consiste à te présenter le mode réel des architectures x86 et x86_64 ainsi que la théorie qui va avec. Foncièrement, ce n'est pas une mauvaise approche, mais elle est lourde et pas spécialement adaptée de nos jours. En effet, le mode réel n'est aujourd'hui utilisé que durant un très court instant lors de l'initialisation du système d'exploitation après quoi il passe en mode protégé ou en mode « long ».

En fait, parler du mode réel a essentiellement du sens lors du développement d'un système d'exploitation, plus précisémment afin de rédiger le programme d'amoçage. Or de ce cadre, la connaissance du mode réel te sera inutile parce qu'il n'est pas employé.

+0 -0

Tant qu'à faire un cours d'assembleur x86/x64, ça serait vraiment bien si on pouvait avoir quelque choses qui à la fois commence par le plus simple et qui va jusqu'aux bout en incluant les instructions les plus modernes (je pense à SSE par exemple). Parce que par exemple pour SSE, pas facile de trouver quelque chose de vraiment clair; ou même pour les instructions du FPU (x87&Co.).

+0 -0

Tant qu'à faire un cours d'assembleur x86/x64, ça serait vraiment bien si on pouvait avoir quelque choses qui à la fois commence par le plus simple et qui va jusqu'aux bout en incluant les instructions les plus modernes (je pense à SSE par exemple). Parce que par exemple pour SSE, pas facile de trouver quelque chose de vraiment clair; ou même pour les instructions du FPU (x87&Co.).

QuentinC

La question qu'il faut savoir, c'est à qui s'adresse le tutoriel de @Dominus. Car entre la personne qui veut découvrir l'assembleur pour savoir ce que c'est, et celle qui veut faire un compilateur, c'est assez différent je pense…

La question qu'il faut savoir, c'est à qui s'adresse le tutoriel de @Dominus. Car entre la personne qui veut découvrir l'assembleur pour savoir ce que c'est, et celle qui veut faire un compilateur, c'est assez différent je pense…

Est ce que c'est incompatible. Techniquement les deux ont besoin de la même base. Simplement le premier n'a pas besoin d'aller à la fin.

Ce n'est pas forcément incompatible, seulement si Dominus ne s'intéresse qu'au premier type…

Après, s'adresser à des débutants et à des gens confirmer, je trouve ça toujours difficile car le niveau de détail n'est jamais le même, et satisfaire les deux, c'est difficile à mon avis.

(opinion personnelle) Dominus Carnufex a raison : l'assembleur, c'est compliqué et les ressources d'apprentissages en ligne ne sont pas forcément bien faites. (fin opinion personnelle)

A l'époque d'Apollo 11, les CPUs étaient très simples, avec peu d'instructions, peu de périphériques extérieurs, peu de mémoire. Donc on ne faisait que des choses simples, parce que chaque instruction en plus peut introduire des bugs, et pèse N bits de plus en mémoire (très chère à l'époque).

Aujourd'hui, une carte de développement comme le CHIP qui coûte 9$, pas forcément puissante, te donne accès à un ensemble d'instructions en assembleur qui est énorme. Le moindre programme pèse plusieurs centaines de Ko (fait un HelloWorld en C, regarde la taille de l'exécutable généré), a beaucoup de fonctionnalités (appel à des libs externes, etc) et écrit sur le système de fichier et cause à d'autres sur Internet. Programmer tout ça en assembleur serait tout bonnement impossible, et même si tu y arrivais, qui accepterait de t'aider à écrire de l'assembleur ? Comprendre la sémantique d'un programme juste en lisant de l'assembleur c'est super compliqué, et ça amène de la complexité là où on n'en n'a pas forcément besoin.

Si tu es anglophone, l'Université de Cambridge a fait un petit projet sur Raspberry pi pour écrire un OS en assembleur. Par contre faut s'accrocher.

Édit Arius : suppression de la remarque sur OC qui n'a rien à faire ici.

+0 -0

Après, s'adresser à des débutants et à des gens confirmer, je trouve ça toujours difficile car le niveau de détail n'est jamais le même, et satisfaire les deux, c'est difficile à mon avis.

Saroupille

Je pars du principe que des gens confirmés en assembleur, il n’y en a quasiment pas, et que lorsqu’ils existent, ils n’ont pas besoin de mon cours : ils sont capables d’aller lire les manuels d’Intel.

Donc mon cours s’adresse à des gens débutants en assembleur, et afin de m’adresser à un public le plus large possible, je ne présuppose aucune connaissance préalable en programmation. Même si savoir programmer dans un langage donné ne va de toute façon pas beaucoup vous aider pour la programmation assembleur…

Et même si j’espère bien qu’à l’issue de mon cours, le lecteur aura une maîtrise suffisante de l’assembleur pour écrire un OS si ça l’amuse, il lui manquera malgré tout un cours de théorie des OS pour réellement le faire.

Parce que par exemple pour SSE, pas facile de trouver quelque chose de vraiment clair; ou même pour les instructions du FPU (x87&Co.).

QuentinC

Je ferai mon maximum pour rendre ça sexy, mais faut pas se leurrer : les instructions SSE, et les instructions SIMD de manière générale, c’est beaucoup du catalogue.

Si tu es anglophone, l'Université de Cambridge a fait un petit projet sur Raspberry pi pour écrire un OS en assembleur. Par contre faut s'accrocher.

ntimeu

Ouais, c’est bien de ce cours d’assembleur ARM que je parlais dans mon premier message. :)

Bref, TL;DR, si vous voulez vous faire une idée de mon cours d’assembleur, c’est par ici.

+0 -0

afin de m’adresser à un public le plus large possible, je ne présuppose aucune connaissance préalable en programmation.

C'est bien sûr ton choix en tant qu'auteur, mais je ne sais pas s'il y a beaucoup de débutants complets en programmation qui veulent apprendre l'assembleur (et je doute fort que ce soit une bonne idée pour eux), et a contrario, pouvoir s'appuyer sur des notions comme les boucles peut sans doute aider à expliquer les sauts, par exemple.

Est-ce que du coup tu ne crains pas de perdre beaucoup de temps à expliquer des choses à des lecteurs qui les connaissent déjà ?

Est-ce que du coup tu ne crains pas de perdre beaucoup de temps à expliquer des choses à des lecteurs qui les connaissent déjà ?

Eusèbe

Je trouve qu'il va justement assez vite sur certaines choses comme le complément à 2, c'est clair et c'est une bonne chose pour ceux qui connaissent de ne pas faire un chapitre dessus mais si tu n'en a jamais entendu parler ça peut sembler rapide bien qu'assez bien expliqué.

Petite question, puisque tu as prévenu qu'il fallait utiliser la console, pourquoi sous windows tu préfère appeler MessageBoxA plutôt que printf ? LE résultat serait moins divergeant par rapport à la version linux…

Sauf erreur, printf et la majorité du reste de la bibliothèque C se trouve dans msvcrt.dll, donc ça ne changerait pas grand chose.

+0 -0

Y’a plusieurs raisons à cela.

  • printf, c’est une fonction qui peut prendre un nombre variable d’arguments, et avec l’ABI Windows, ça veut dire parler de la pile dès le cinquième argument, ce que je n’ai pas envie d’aborder aussi tôt dans le cours.
  • Mon TP consiste précisément à trouver comment convertir un nombre en chaîne de caractères, et par là-même à montrer aux lecteurs pourquoi l’assembleur, c’est dur : s’ils connaissent déjà printf, ça perd tout son sens.
  • Les windowsiens vont être pas mal laissés de côté dans un premier temps, je « compense » en leur offrant un Hello World plus stylé que les autres.
  • L’idée. dans un premier temps, est d’utiliser uniquement les possibilités natives du système d’exploitation, et de voir plus tard pour la communication avec des bibliothèques tierces. D’où le fait d’utiliser les appels système sous les unixoïdes, et l’API Win64 sous Windows.
+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte