
                                Assembly HOWTO

Franois-Ren Rideau rideau@ens.fr

   v0.4l, 16 Novembre 1997
     _________________________________________________________________

   _(Version franaise ralise par Eric Dumas dumas@freenix.fr
   dumas@Linux.EU.Org, et Far Rideau rideau@ens.fr, 11 Novembre 1997).
   Ce document dcrit comment programmer en assembleur x86 en n'utilisant
   que des outils de dveloppement libres, et tout particulirement avec
   le systme d'exploitation Linux sur la plate-forme i386. Les
   informations contenues dans ce document peuvent tre applicables ou
   non applicables  d'autres plates-formes matrielles ou logicielles.
   Les contributions  ce documents seront acceptes avec gratitude.
   mots-clefs: assembleur, libre, macroprocesseur, prprocesseur, asm,
   inline asm, 32 bits, x86, i386, gas, as86, nasm_
     _________________________________________________________________

1. Introduction

1.1 Copyright

   Copyright  1996,1997 Franois-Ren Rideau. Ce document peut tre
   redistribu sous les termes de la license LDP, disponibles 
   http://sunsite.unc.edu/LDP/COPYRIGHT.html.

1.2 Note importante

   Ceci est cens tre la dernire version que j'crirai de ce document.
   Il y a un candidat pour reprendre en charge le document, mais jusqu'
   ce qu'il le reprenne compltement en main, je serai heureux de
   m'occuper de tout courrier concernant ce document.

   Vous tes tout spcialement invits  poser des questions,  y
   rpondre,  corriger les donnes,  ajouter de nouvelles informations,
    complter les rfrences sur d'autres logiciels,  mettre en
   vidence les erreurs et lacunes du document. Si vous tes motivs,
   vous pouvez mme _prendre en charge ce document_. En un mot, apporter
   votre contribution!

   Pour contribuer  ce document, contactez la personne qui apparat
   actuellement en charge. Au moment o j'cris ces lignes, il s'agit de
   Franois-Ren Rideau) ainsi que de Paul Anderson.

1.3 Avant-Propos

   Ce document est destin  rpondre aux questions les plus frquemment
   poses par les gens qui dveloppent ou qui souhaitent dvelopper des
   programmes en assembleurs x86 32 bits en utilisant des logiciels
   _libres_, et tout particulirement sous Linux. Vous y trouverez
   galement des liens sur d'autres documents traitant d'assembleur,
   fonds sur des outils logiciels qui ne sont pas libres, pas 32-bit, ou
   pas ddis  l'architecture x86, bien que cela ne soit pas le but
   principal de ce document.

   Etant donn que l'intret principal de la programmation en assembleur
   est d'tablir les fondations de systmes d'exploitation,
   d'interprteurs, de compilateurs, et de jeux, l o un compilateur C
   n'arrive plus  fournir le pouvoir d'expression ncessaire (les
   performances tant de plus en plus rarement un problme), nous
   insisteront sur le dveloppement de tels logiciels.

  Comment utiliser ce document

   Ce document contient des rponses  un certain nombre de questions
   frquemment poses. Des URL y sont donns, qui pointent sur des sites
   contenant documents ou logiciels. Prenez conscience que les plus
   utiles de ces sites sont dupliqus sur des serveurs miroirs, et qu'en
   utilisant le site miroir le plus proche de chez vous, vous vitez  un
   gchis inutile aussi bien de prcieuses ressources rseau communes 
   l'Internet que de votre propre temps. Ainsi, il existe un certain
   nombre de gros serveurs dissmins sur la plante, qui effectuent la
   duplication d'autres sites importants. Cherchez o se trouvent ces
   sites et identifiez les plus proches de chez vous (du point de vue du
   rseau). Parfois, la liste des miroirs est donnes dans un fichier ou
   dans le message de connexion. Suivez ces conseils. Si ces informations
   ne sont pas prsentes, utilisez le programme archie.

   La version la plus rcente de ce document peut tre trouve sur

   http://www.eleves.ens.fr:8080/home/rideau/Assembly-HOWTO ou
   http://www.eleves.ens.fr:8080/home/rideau/Assembly-HOWTO.sgml

   mais les rpertoires de HowTo Linux _devraient_ normalement tre  peu
   prs  jour (je ne peux pas le garentir):

   ftp://sunsite.unc.edu/pub/Linux/docs/HOWTO/ (?)

   La version franaise de ce document peut tre trouve sur le site

   ftp://ftp.ibp.fr/pub/linux/french/HOWTO/

  Autres documents de rfrence

     * si vous ne savez ce qu'est le _libre_ logiciel, lisez avec
       attention la GPL (GNU General Public License), qui est utilise
       dans un grand nombre de logiciels libres, et est une source
       d'inspiration pour la plupart des autres licences d'utilisations
       de logiciels libres. Elle se trouve gnralement dans un fichier
       nomm COPYING, avec une version pour les bibliothques de routines
       dans un fichier nomm COPYING.LIB. Les crits publis par la FSF
       (free software foundation) peuvent galement vous aider 
       comprendre le phnomne.
     * plus prcisment, les logiciels libres intressants sont ceux
       desquels les sources sont disponibles, que l'on peut consulter,
       corriger, et desquels on peut emprunter une partie. Lisez les
       licences d'utilisation avec attention et conformez-vous y.
     * il existe une FAQ dans le forum de discussion comp.lang.asm.x86
       qui rpond aux questions gnrales concernant la programmation en
       assembleur pour x86, et aux questions concernant certains
       assembleurs commerciaux dans un environnement DOS 16 bits.
       Certaines de ces rponses peuvent s'appliquer  la programmation
       32 bits, aussi serez-vous sans-doute intresss de lire cette
       FAQ... http://www2.dgsys.com/~raymoon/faq/asmfaq.zip
     * Sont disponibles des FAQs, de la documentation, et des sources,
       concernant la programmation sur votre plate-forme prfre,
       quelqu'elle soit, et vous devriez les consulter pour les problmes
       lis  votre plate-forme qui ne seraient pas spcifique  la
       programmation en assembleur.

1.4 Historique de document

   Chaque version inclue quelques modifications et corrections mineures,
   qui ne sont pas indiques  chaque fois.

   _Version 0.1 23 Avril 1996_
          Francois-Rene "Far" Rideau <rideau@ens.fr> cre et diffuse
          initialement le document sous forme d'un mini-HOWTO car ``Je
          suis un peu fatigu d'avoir  rpondre encore et toujours aux
          mmes questions dans le forum comp.lang.asm.x86''

   _Version 0.2 4 Mai 1996_
          *

   _Version 0.3c 15 Juin 1996_
          *

   _Version 0.3f 17 Octobre 1996_
          Tim Potter indique l'option -fasm pour activer l'assembleur
          en-ligne de GCC sans le reste des optimisations de -O.

   _Version 0.3g 2 Novembre 1996_
          Cration de l'historique. Ajout de pointeurs dans la section
          sur la compilation croise. Ajout d'une section concernant la
          programmation des entres/sorties sous Linux (en particulier
          pour l'accs vido).

   _Version 0.3h 6 Novembre 1996_
          plus sur la compilation croise - voir sur sunsite:
          devel/msdos/

   _Version 0.3i 16 Novembre 1996_
          NASM commence  tre particulirement intressant

   _Version 0.3j 24 Novembre 1996_
          Rfrence sur la version franaise

   _Version 0.3k 19 Dcembre 1996_
          Quoi? J'avais oubli de parler de Terse?

   _Version 0.3l 11 Janvier 1997_
          *

   _Version 0.4pre1 13 Janvier 1997_
          Le mini-HOWTO au format texte est transform en un authentique
          HOWTO au format linuxdoc-sgml, pour explorer les possibilits
          dudit format.

   _Version 0.4 20 Janvier 1997_
          Premire diffusion de ce HOWTO.

   _Version 0.4a 20 Janvier 1997_
          Ajout de la section CREDITS

   _Version 0.4b 3 Fvrier 1997_
          NASM mis avant AS86

   _Version 0.4c 9 Fvrier 1997_
          Ajout de la partie "Avez-vous besoin d'utilisateur
          l'assembleur?"

   _Version 0.4d 28 Fvrier 1997_
          Annonce fantme d'un nouveau responsable de ce HowTo.

   _Version 0.4e 13 Mar 1997_
          Version diffuse pour DrLinux

   _Version 0.4f 20 Mars 1997_
          *

   _Version 0.4g 30 Mars 1997_
          *

   _Version 0.4h 19 Juin 1997_
          Ajouts  propos de "Comment ne pas utiliser l'assembleur";
          mises  jour concernant NASM et GAS.

   _Version 0.4i 17 Juillet 1997_
          Informations sur l'accs au mode 16 bits  partir de Linux.

   _Version 0.4j 7 September 1997_
          *

   _Version 0.4k 19 Octobre 1997_
          je (Far) reprends en main la traduction franaise du HowTo

   _Version 0.4l 16 Novembre 1997_
          version pour LSL 6me dition.

          Il s'agit encore d'une nouvelle ``toute dernire version
          ralise par Far avant qu'un nouveau responsable ne prenne la
          main''.

1.5 Crdits

   Je souhaiterais remercier les personnes suivantes:
     * Linus Torvalds pour Linux
     * Bruce Evans pour bcc d'o as86 est extrait
     * Simon Tatham et Julian Hall pour NASM.
     * Jim Neil pour Terse
     * Greg Hankins pour la coordination des HOWTOs
     * Raymond Moon pour sa FAQ
     * Eric Dumas pour la traduction initiale en franais... (l'auteur,
       franais, est le premier attrist de devoir crire l'original en
       anglais)
     * Paul Anderson et Rahim Azizarab pour m'avoir aid,  dfaut de
       reprendre le HowTo en main.
     * toutes les personnes qui ont contribu  l'criture de ce
       document, par leurs ides, remarques ou leur soutient moral.

2. Avez-vous besoin de l'assembleur?

   Je ne veux en aucun cas jouer les empcheurs-de-tourner-en-rond, mais
   voici quelques conseils issus d'une exprience gagne  la dure.

2.1 Le Pour et le Contre

  Les avantages de l'assembleur

   L'assembleur peut vous permettre de raliser des oprations trs bas
   niveau:
     * vous pouvez accder aux registres et aux ports d'entres/sorties
       spcifiques  votre machine;
     * vous pouvez parfaitement contrler le comportemant du code dans
       des sections critiques o pourraient sinon advenir un blocage du
       processeur ou des priphriques;
     * vous pouvez sortir des conventions de production de code de votre
       compilateur habituel; ce qui peut vous permettre d'effectuer
       certaines optimisations (par exemple contourner les rgles
       d'allocation mmoire, grer manuellement le cours de l'xcution,
       etc.);
     * accder  des modes de programmation non courants de votre
       processeur (par exemple du code 16 bits pour l'amorage ou
       l'interfaage avec le BIOS, sur les pcs Intel);
     * vous pouvez construire des interfaces entre des fragments de codes
       utilisant des conventions incompatibles (c'est--dire produit par
       des compilateurs diffrents ou spars par une interface
       bas-niveau);
     * vous pouvez gnrer un code assez rapide pour les boucles
       importantes pour pallier aux dfauts d'un compilateur qui ne sait
       les optimiser (mais bon, il existe des compilateurs optimisateurs
       librement disponibles!);
     * vous pouvez gnrer du code optimis " la main" qui est plus
       parfaitement rgl pour votre configuration matrielle prcise,
       mme s'il ne l'est pour aucune autre configuration;
     * vous pouvez crire du code pour le compilateur optimisateur de
       votre nouveau langage. (c'est l une activit  laquelle peu se
       livrent, et encore, rarement.)

  Les inconvnients de l'assembleur

   L'assembleur est un langage trs bas niveau (le langage du plus bas
   niveau qui soit au dessus du codage  la main de motifs d'instructions
   en binaire). En consquence:
     * l'criture de code en est longue et ennuyeuse;
     * les bogues apparaissent aisment;
     * les bogues sont difficiles  reprer et supprimer;
     * il est difficile de comprendre et de modifier du code (la
       maintenance est trs complique);
     * le rsultat est extrmement peu portable vers une autre
       architecture, existante ou future;
     * votre code ne sera optimis que une certaine implmentation d'une
       mme architecture: ainsi, parmi les plates-formes compatibles
       Intel, chaque ralisation d'un processeur et de ses variantes
       (largeur du bus, vitesse et taille relatives des
       CPU/caches/RAM/Bus/disques, prsence ou non d'un coprocesseur
       arithmtique, et d'extensions MMX ou autres) implique des
       techniques d'optimisations parfois radicalement diffrentes. Ainsi
       diffrent grandement les processeurs dj existant et leurs
       variations: Intel 386, 486, Pentium, PPro, Pentium II; Cyrix 5x86,
       6x86; AMD K5, K6. Et ce n'est srement pas termin: de nouveaux
       modles apparaissent continuellement, et cette liste mme sera
       rapidement dpasse, sans parler du code ``optimis'' qui aura t
       crit pour l'un quelconque des processeurs ci-dessus.
     * le code peut galement ne pas tre portable entre diffrents
       systmes d'exploitation sur la mme architecture, par manque
       d'outils adapts (GAS semble fonctionner sur toutes les
       plates-formes; NASM semble fonctionner ou tre facilement
       adaptable sur toutes les plates-formes compatibles Intel);
     * un temps incroyable de programmation sera perdu sur de menus
       dtails, plutt que d'tre efficacement utilis pour la conception
       et le choix des algorithmes utiliss, alors que ces derniers sont
       connus pour tre la source de la majeure partie des gains en
       vitesse d'un programme. Par exemple, un grand temps peut tre
       pass  grapiller quelques cycles en crivant des routines rapides
       de manipulation de chanes ou de listes, alors qu'un remplacement
       de la structure de donnes  un haut niveau, par des arbres
       quilibrs et/ou des tables de hachage permettraient immdiatement
       un grand gain en vitesse, et une paralllisation aise, de faon
       portable permettant un entretien facile.
     * une petite modification dans la conception algorithmique d'un
       programme anantit la validit du code assembleur si patiemment
       labor, rduisant les dveloppeurs au dilemne de sacrifier le
       fruit de leur labeur, ou de s'enchaner  une conception
       algorithmique obsolte.
     * pour des programmes qui fait des choses non point trop loignes
       de ce que font les benchmarks standards, les
       compilateurs/optimiseurs commerciaux produisent du code plus
       rapide que le code assembleur crit  la main (c'est moins vrai
       sur les architectures x86 que sur les architectures RISC, et sans
       doute moins vrai encore pour les compilateurs librement
       disponible. Toujours est-il que pour du code C typique, GCC est
       plus qu'honorable).
     * Quoi qu'il en soit, ains le dit le saige John Levine, modrateur
       de comp.compilers, "les compilateurs rendent aise l'utilisation
       de structures de donnes complexes; ils ne s'arrtent pas, morts
       d'ennui,  mi-chemin du travail, et produisent du code de qualit
       tout  fait satisfaisante". Ils permettent galement de propager
       _correctement_ les transformations du code  travers l'ensemble du
       programme, aussi hnaurme soit-il, et peuvent optimiser le code
       par-del les frontires entre procdures ou entre modules.

  Affirmation

   En pesant le pour et le contre, on peut conclure que si l'assembleur
   est parfois ncessaire, et peut mme tre utile dans certains cas o
   il ne l'est pas, il vaut mieux:
     * minimiser l'utilisation de code crit en assembleur;
     * encapsuler ce code dans des interfaces bien dfinies;
     * engendrer automatiquement le code assembleur  partir de motifs
       crits dans un langage plus de haut niveau que l'assembleur (par
       exemple, des macros contenant de l'assembleur en-ligne, avec GCC);
     * utiliser des outils automatiques pour transformer ces programmes
       en code assembleur;
     * faire en sorte que le code soit optimis, si possible;
     * utiliser toutes les techniques prcdentes  la fois, c'est--dire
       crire ou tendre la passe d'optimisation d'un compilateur.

   Mme dans les cas o l'assembleur est ncessaire (par exemple lors de
   dveloppement d'un systme d'exploitation), ce n'est qu' petite dose,
   et sans infirmer les principes ci-dessus.

   Consultez  ce sujet les sources du noyau de Linux: vous verrez qu'il
   s'y trouve juste le peu qu'il faut d'assembleur, ce qui permet d'avoir
   un systme d'exploitation rapide, fiable, portable et d'entretien
   facile. Mme un jeu trs clbre comme DOOM a t en sa plus grande
   partie crit en C, avec une toute petite routine d'affichage en
   assembleur pour acclrer un peu.

2.2 Comment ne pas utiliser l'assembleur

  Mthode gnrale pour obtenir du code efficace

   Comme le dit Charles Fiterman dans comp.compilers  propos de la
   diffrence entre code crit par l'homme ou la machine,

   ``L'homme devrait toujours gagner, et voici pourquoi:
     * Premirement, l'homme crit tout dans un langage de haut nivrau.
     * Deuximement, il mesure les temps d'xcution (profiling) pour
       dterminer les endroits o le programme passe la majeure partie du
       temps.
     * Troisimement, il demande au compilateur d'engendrer le code
       assembleur produit pour ces petites sections de code.
     * Enfin, il effectue  la main modifications et rglages,  la
       recherche des petites amliorations possibles par rapport au code
       engendr par la machine.

   L'homme gagne parce qu'il peut utiliser la machine.''

  Langages avec des compilateurs optimisateurs

   Des langages comme ObjectiveCAML, SML, CommonLISP, Scheme, ADA,
   Pascal, C, C++, parmi tant d'autres, ont tous des compilateurs
   optimiseurs librement disponibles, qui optimiseront le gros de vos
   programmes, et produiront souvent du code meilleur que de l'assembleur
   fait-main, mme pour des boucles serres, tout en vous permettant de
   vous concentrer sur des dtails haut niveau, et sans vous interdire de
   gagner par la mthode prcdente quelques pourcents de performance
   supplmentaire, une fois la phase de conception gnrale termine.
   Bien sr, il existe galement des compilateurs optimiseurs commerciaux
   pour la plupart de ces langages.

   Certains langages ont des compilateurs qui produisent du code C qui
   peut ensuite tre optimis par un compilateur C. C'est le cas des
   langages LISP, Scheme, Perl, ainsi que de nombreux autres. La vitesse
   des programmes obtenus est toute  fait satisfaisante.

  Procdure gnrale  suivre pour acclerer votre code

   Pour acclrer votre code, vous ne devriez traiter que les portions
   d'un programme qu'un outil de mesure de temps d'xcution (profiler)
   aura identifi comme tant un goulot d'tranglement pour la
   performance de votre programme.

   Ainsi, si vous identifiez une partie du code comme tant trop lente,
   vous devriez
     * d'abord essayer d'utiliser un meilleur algorithme;
     * essayer de la compiler au lieu de l'interprter;
     * essayer d'activer les bonnes options d'optimisation de votre
       compilateur;
     * donner au compilateur des indices d'optimisation (dclarations de
       typage en LISP; utilisation des extensions GNU avec GCC; la
       plupart des compilos fourmillent d'options);
     * enfin de compte seulement, se mettre  l'assembleur si ncessaire.

   Enfin, avant d'en venir  cette dernire option, vous devriez
   inspecter le code gnr pour vrifier que le problme vient
   effectivement d'une mauvaise gnration de code, car il se peut fort
   bien que ce ne soit pas le cas: le code produit par le compilateur
   pourrait tre meilleur que celui que vous auriez crit, en particulier
   sur les architectures modernes  pipelines multiples! Il se peut que
   les portions les plus lentes de votre programme le soit pour des
   raisons intrinsques. Les plus gros problmes sur les architectures
   modernes  processeur rapide sont dues aux dlais introduits par les
   accs mmoires, manqus des caches et TLB, fautes de page;
   l'optimisation des registres devient vaine, et il vaut mieux repenser
   les structures de donnes et l'enchanement des routines pour obtenir
   une meilleur localit des accs mmoire. Il est possible qu'une
   approche compltement diffrente du problme soit alors utile.

  Inspection du code produit par le compilateur

   Il existe de nombreuses raisons pour vouloir regarder le code
   assembleur produit par le compilateur. Voici ce que vous pourrez faire
   avec ce code:
     * vrifier si le code produit peut ou non tre amliorer avec du
       code assembleur crit  la main (ou par un rglage diffrent des
       options du compilateur);
     * quand c'est le cas, commencer  partir de code automatiquement
       engendr et le modifier plutt que de repartir de zro;
     * plus gnralement, utilisez le code produit comme des scions 
       greffer, ce qui  tout le moins vous laisse permet d'avoir
       gratuitement tout le code d'interfaage avec le monde extrieur.
     * reprer des bogues ventuels dus au compilateur lui-mme
       (esprons-le trs rare, quitte  se restreindre  des versions
       ``stables'' du compilo).

   La manire standard d'obtenir le code assembleur gnr est d'appeller
   le compilateur avec l'option -S. Cela fonctionne avec la plupart des
   compilateur Unix y compris le compilateur GNU C (GCC); mais  vous de
   voir dans votre cas. Pour ce qui est de GCC, il produira un code un
   peu plus comprhensible avec l'option -fverbose-asm. Bien sur, si vous
   souhaitez obtenir du code assembleur optimis, n'oubliez pas d'ajouter
   les options et indices d'optimisation appropries!

3. Assembleurs

3.1 Assembleur en-ligne de GCC

   Le clbre GNU C/C++ Compiler (GCC), est un compilateur 32 bits
   optimisant situ au coeur du projet GNU. Il gre assez bien les
   architectures x86 et permet d'insrer du code assembleur  l'intrieur
   de programmes C de telle manire que les registres puissent tre soit
   spcifis soit laiss aux bons soins de GCC. GCC fonctionne sur la
   plupart des plates-formes dont Linux, *BSD, VSTa, OS/2, *DOS, Win*,
   etc.

  O trouver GCC

   Le site principal de GCC est le site FTP du projet GNU:
   ftp://prep.ai.mit.edu/pub/gnu/ On y trouve galement toutes les
   applications provenant du projet GNU. Des versions configures ou
   prcompiles pour Linux sont disponibles sur
   ftp://sunsite.unc.edu/pub/Linux/GCC/. Il existe un grand nombre de
   miroirs FTP des deux sites partout de par le monde, aussi bien que des
   copies sur CD-ROM.

   Le groupe de dveloppement de GCC s'est rcemment scind en deux; pour
   plus d'informations sur la version exprimentale, egcs, voir
   http://www.cygnus.com/egcs/

   Les sources adapts  votre systme d'exploitation prfr ainsi que
   les binaires prcompils peuvent tre trouvs sur les sites FTP
   courants.

   Le portage le plus clbre de GCC pour DOS est DJGPP et il peut tre
   trouv dans le rpertoire du mme nom sur les sites ftp. Voir:

   http://www.delorie.com/djgpp/

   Il existe galement un portage de GCC pour OS/2 appel EMX qui
   fonctionne galement sous DOS et inclut un grand nombre de routines
   d'mulation Unix. Voir les sites

   http://www.leo.org/pub/comp/os/os2/gnu/emx+gcc/

   http://warp.eecs.berkeley.edu/os2/software/shareware/emx.html

   ftp://ftp-os2.cdrom.com/pub/os2/emx09c/

  O trouver de la documentation sur l'assembleur en ligne avec GCC?

   La document de GCC inclus les fichiers de documentation au format
   texinfo. Vous pouvez les compiler avec TeX et les imprimer, ou les
   convertir au format .info et les parcourir interactivement avec emacs,
   ou encore les convertir au format HTML, ou en  peu prs n'importe
   quel format (avec les outils adquats). Les fichiers .info sont
   gnralement installs en mme temps que GCC.

   La section  consulter est C Extensions::Extended Asm::

   La section Invoking GCC::Submodel Options::i386 Options:: peut
   galement vous aider. En particulier, elle donne les noms de
   contraintes pour les registres du i386: abcdSDB correspondent
   respectivement  %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp (aucune
   lettre pour %esp).

   Le site "DJGPP Games resource" (qui n'est pas rserv aux seuls
   dveloppeurs de jeux) possde une page particulire sur l'assembleur:

   http://www.rt66.com/~brennan/djgpp/djgpp_asm.html

   Enfin, il existe une page de la Toile appele "DJGPP Quick ASM
   Programming Guide", contenant des URL sur des FAQ, la syntaxe
   assembleur AT&T x86, des informations sur l'assembleur en ligne, et la
   conversion des fichiers .obj/.lib:

   http://remus.rutgers.edu/~avly/djasm.html

   GCC soutraite l'assemblage proprement dit  GAS et suit donc sa
   syntaxe (voir plus bas), cela implique que l'assembleur en ligne doit
   utiliser des caractres pourcents entre apostrophes pour qu'ils soient
   passs  GAS. Voir la section ddie  GAS.

   Vous trouverez un _grand_ nombre d'exemples instructifs dans le
   rpertoire linux/include/asm-i386/ des sources de Linux.

  Appeller GCC pour obtenir du code assembleur en ligne correcte?

   Assurez-vous d'appeller gcc avec l'option -O (ou -O2, -O3, etc) pour
   activer les optimisations et l'assembleur en ligne. Si vous ne le
   fates pas, votre code pourra compiler mais ne pas s'excuter
   correctement!! En fait (merci  Tim Potter, timbo@moshpit.air.net.au),
   il suffit d'utiliser l'option -fasm, faisant partie de toutes les
   fonctionnalits actives par l'option -O. Donc si vous avez des
   problmes en raison d'optimisations bogues dans votre implmentation
   de gcc, vous pouvez toujours utiliser l'assembleur en ligne. De mme,
   utilisez l'option -fno-asm pour dsactiver l'assembleur en ligne (on
   peut se demander pourquoi?).

   Plus gnralement, les bonnes options de compilation  utiliser avec
   gcc sur les plates-formes x86 sont
     _________________________________________________________________

        gcc -O2 -fomit-frame-pointer -m386 -Wall
     _________________________________________________________________

   -O2 est le bon niveau d'optimisation. Les optimisations suprieures
   gnrent un code un peu plus important, mais trs lgrement plus
   rapide. De telles sur-optimisations peuvent tre utiles que dans le
   cas d'optimisations de boucles que vous pouvez toujours raliser en
   assembleur. Si vous avez besoin de faire ce genre de choses, ne le
   fates que pour les routines qui en ont besoin.

   -fomit-frame-pointer permet au code gnr de se passer de la gestion
   inutile des pointeurs de fentre, ce qui rend le code plus petit plus
   rapide et libre un registre pour de plus amples optimisations. Cette
   option exclue l'utilisation des outils de dboggage (gdb), mais
   lorsque vous les utilisez, la taille et la vitesse importent peu.

   -m386 gnre un code plus compacte sans ralentissement notable, (moins
   de code signifie galement mois d'entres/sorties sur disque et donc
   une excution plus rapide). Vous pouvez galement utiliser l'option
   -mpentium sur la version GCC grant l'optimisation pour ce processeur.

   -Wall active toutes les mises-en-garde (warning) et vous vite de
   nombreuses erreurs stupides et videntes.

   Pour optimiser encore plus, vous pouvez utiliser l'option -mregparm=2
   et/ou les attributs de fonctions qui peuvent tre utiliss mais ils
   peuvent dans certains cas poser de nombreux problmes lors de
   l'dition de liens avec du code externe (notamment les bibliothques
   partages)...

   Notez que vous pouvez ajoutez ces options aux options utilises par
   dfaut sur votre systme en ditant le fichier
   /usr/lib/gcc-lib/i486-linux/2.7.2.3/specs (cependant, ne rajoutez pas
   -Wall  ces options).

3.2 GAS

   GAS est l'assembleur GNU, utilis par gcc.

  O le trouver?

   Au mme endroit o vous avez trouv gcc, dans le paquetage binutils.

  Qu'est-ce que la syntaxe AT&T

   Comme GAS a t invent pour supporter un compilateur 32 bits sous
   unix, il utilise la syntaxe standard "AT&T", qui ressemblent assez 
   l'assembleur m68k. La syntaxe n'est ni pire, ni meilleur que la
   syntaxe "Intel". Elle est juste diffrente. Lorsque vous aurez
   l'habitude de vous en servir, vous la trouverez plus rgulire que la
   syntaxe Intel, quoique que lgrement plus ennuyeuse aussi.

   Voici les points les plus importants  propos de la syntaxe de GAS:
     * Les noms de registres sont prfixs avec %, de faon que les
       registres sont %eax, %dl et consorts au lieu de juste eax, dl,
       etc. Ceci rend possible l'inclusion directe de noms de symboles
       externes C sans risque de confusion, ou de ncessit de prfixes
       _.
     * L'ordre des oprandes est source(s) d'abord, destination en
       dernier,  l'oppos de la convention d'intel consistant  mettre
       la destination en premier, les source(s) ensuite. Ainsi, ce qui en
       syntaxe intel s'crit mov ax,dx (affecter au registre ax le
       contentu du registre dx) s'crira en syntaxe att mov %dx, %ax.
     * La longueur des oprandes est spcifie comme suffixe du nom
       d'instruction. Le suffixe est b pour un octet (8 bit), w pour un
       mot (16 bit), et l pour un mot long (32 bit). Par exemple, la
       syntaxe correcte pour l'instruction ci-dessus aurait d tre movw
       %dx,%ax. Toutefois, gas n'est pas trop aussi strict que la syntaxe
       att l'exige, et le suffixe est optionel quand la longueur peut
       tre devine grce aux oprandes qui sont des registres, la taille
       par dfaut tant 32 bit (avec une mise en garde quand on y fait
       appel).
     * Les oprandes immediates sont marqus d'un prfixe $, comme dans
       addl $5,%eax (ajouter la valeur longue immdiate 5 au registre
       %eax).
     * L'absence de prfixe  une oprande indique une adresse mmoire;
       ainsi movl $foo,%eax met l'_adresse_ de la variable foo dans le
       registre %eax, tandis que movl foo,%eax met le contenu de la
       variable foo dans le registre %eax.
     * L'indexation ou l'indirection se fait en mettant entre parenthses
       le registre d'index ou la case mmoire contenant l'indirection,
       comme dans testb $0x80,17(%ebp) (tester le bit de poids fort de
       l'octet au dplacement 17 aprs la case pointe par %ebp).

   Un programme existe pour vous aider  convertir des programmes crits
   avec la syntaxe TASM en syntaxe AT&T. Voir

   ftp://x2ftp.oulu.fi/pub/msdos/programming/convert/ta2asv08.zip

   GAS possde une documentation complte au format TeXinfo, qui est
   distribue entre autre avec les sources. Vous pouvez parcourir les
   pages .info qui en sont extraites avec Emacs. Il y avait aussi un
   fichier nomm gas.doc ou as.doc disponible autour des sources de GAS,
   mais il a t fusionn avec la documentation TeXinfo. Bien sr, en cas
   de doute, l'ultime documentation est constitue par les sources
   eux-mmes! Une section qui vous intressera particulirement est
   Machine Dependencies::i386-Dependent::

   Les sources de Linux dont un bon exemple: regardez dans le rpertoire
   linux/arch/i386 les fichiers suivants: kernel/*.S,
   boot/compressed/*.S, mathemu/*.S

   Si vous codez ce genre de chose, un paquetage de thread, etc vous
   devriez regarder d'autres langages (OCaml, gforth, etc), ou des
   paquetages sur les thread (QuickThreads, pthreads MIT, LinuxThreads,
   etc).

   Enfin gnrer  partir d'un programme C du code assembleur peut vous
   montrer le genre d'instructions que vous voulez. Consultez la section
   Avez-vous besoin de l'assembleur? au dbut de ce document.

  mode 16 bits limit

   GAS est un assembleur 32 bits, conu pour assembler le code produit
   par un compilateur 32 bits. Il ne reconnat que d'une manire limit
   le mode 16 bits du i386, en ajoutant des prfixes 32 bits aux
   instructions; vous crivez donc en ralit du code 32 bits, qui
   s'excute en mode 16 bits sur un processeur 32 bits. Dans les deux
   modes, il gre les registres 16 bits, mais pas l'adressage 16 bits.
   Utilisez les instructions .code16 et .code32 pour basculer d'un mode 
   l'autre. Notez que l'instruction assembleur en ligne asm(".code16\n")
   autorisera gcc  gnrer du code 32 bits qui fonctionnera en mode
   rl!

   Le code ncessaire pour que GAS gre le mode 16 bits aurait t ajout
   par Bryan Ford ( confirmer?). Toutefois, ce code n'est prsent dans
   aucune distribution de GAS que j'ai essaye (jusqu' binutils-2.8.1.x)
   ... plus d'informations  ce sujet seraient les bienvenues dans ce
   HowTo.

   Une solution bon march pour insrer quelques instructions 16-bit non
   reconnues pas GAS consiste  dfinir des macros (voir plus bas) qui
   produisent directement du code binaire (avec .byte), et ce uniquement
   pour les rares instructions 16 bits dont vous avez besoin (quasiment
   aucunes, si vous utilisez le .code16 prcdement dcrit, et pouvez
   vous permettre de supposer que le code fonctionnera sur un processeur
   32 bits). Pour obtenir le systme de codage correct, vous pouvez vous
   inspirer des assembleurs 16 bits.

3.3 GASP

   GASP est un prprocesseur pour GAS. Il ajoute des macros et une
   syntaxe plus souple  GAS.

  O trouver gasp?

   gasp est livr avec gas dans le paquetage binutils GNU.

  Comment il fonctionne?

   Cela fonctionne comme un filtre, tout comme cpp et ses variantes. Je
   ne connais pas les dtails, mais il est livr avec sa propre
   documentation texinfo, donc consultez-la, imprimez-la, assimilez-la.
   La combinaison GAS/GASP me semble tre un macro-assembleur standard.

3.4 NASM

   Du projet Netwide Assembler est issu encore un autre assembleur, crit
   en C, qui devrait tre assez modulaire pour supporter toutes les
   syntaxes connues et tous les formats objets existants.

  O trouver NASM?

   http://www.cryogen.com/Nasm

   Les versions binaires se trouvent sur votre miroir sunsite habituel
   dans le rpertoire devel/lang/asm/. Il devrait galement tre
   disponible sous forme d'archive .rpm ou .deb parmi les contributions 
   votre distribution prfre RedHat ou Debian.

  Son rle

   Au moment de l'criture de ce HOWTO, NASM en est  la version 0.96.

   La syntaxe est  la Intel. Une gestion de macros est intgre.

   Les formats objets reconnus sont bin, aout, coff, elf, as86, (DOS)
   obj, win32, et rdf (leur propre format).

   NASM peut tre utilise comme assembleur pour le compilateur libre
   LCC.

   Comme NASM volue rapidement, ce HowTo peut ne pas tre  jour  son
   sujet. A moins que vous n'utilisiez BCC comme compilateur 16 bit (ce
   qui dpasse le cadre de ce document), vous devriez utiliser NASM
   plutt que AS86 ou MASM, car c'est un logiciel libre avec un excellent
   service aprs-don, qui tourne sur toutes plateformes logicielles et
   matrielles.

   Note: NASM est galement livr avec un dsassembleur, NDISASM.

   Son analyseur "grammatical", crit  la main, le rend beaucoup plus
   rapide que GAS; en contrepartie, il ne reconnat qu'une architecture,
   en comparaison de la plthore d'architectures reconnues par GAS. Pour
   les plates-formes x86, NASM semble tre un choix judicieux.

3.5 AS86

   AS86 est un assembleur 80x86,  la fois 16 et 32 bits, faisant partie
   du compilateur C de Bruce Evans (BCC). Il possde une syntaxe  la
   Intel.

  Where to get AS86

   Une version compltement dpasse de AS86 est diffuse par HJLu juste
   pour compiler le noyau Linux, dans un paquetage du nom de bin86
   (actuellement version 0.4) disponible dans le rpertoire GCC des sites
   FTP Linux. Je dconseille son utilisation pour toute autre chose que
   compiler Linux. Cette version ne reconnat qu'un format de fichiers
   minix modifi, que ne reconnaissent ni les binutils GNU ni aucun autre
   produit. Il possde de plus certains bogues en mode 32 bits. Ne vous
   en servez donc vraiment que pour compiler Linux.

   Les versions les plus rcentes de Bruce Evans (bde@zeta.org.au) est
   diffuse avec la distribution FreeBSD. Enfin, elles l'taient! Je n'ai
   pas pu trouver les sources dans la distribution 2.1. Toutefois, vous
   pouvez trouver les sources dans

   http:///www.eleves.ens.fr:8080/home/rideau/files/bcc-95.3.12.src.tgz

   Le projet Linux/8086 (galement appel ELKS) s'est d'une certaine
   manire charge de maintenir bcc (mais je ne crois pas qu'ils aient
   inclus les patches 32 bits). Voir les sites
   http://www.linux.org.uk/Linux8086.html et ftp://linux.mit.edu/.

   Entre autres choses, ces versions plus rcentes,  la diffrence de
   celle de HJLu, grent le format a.out de Linux; vous pouvez donc
   effectuer des ditions de liens avec des programmes Linux, et/ou
   utiliser les outils habituels provenant du paquetage binutils pour
   manipuler vos donnes. Cette version peut co-exister sans problme
   avec les versions prcdentes (voir la question  ce sujet un peu plus
   loin).

   La version du 12 mars 1995 de BCC ainsi que les prcdentes a un
   problme qui provoque la gnration de toutes les oprations
   d'empilement/dpilement de segments en 16 bits, ce qui est
   particulirement ennuyant lorsque vous dveloppez en mode 32 bits. Un
   patch est diffus par le projet Tunes

   http://www.eleves.ens.fr:8080/home/rideau/Tunes/

    partir du lien suivant: files/tgz/tunes.0.0.0.25.src.tgz ou dans le
   rpertoire LLL/i386/.

   Le patch peut galement tre directement rcupr sur

   http://www.eleves.ens.fr:8080/home/rideau/files/as86.bcc.patch.gz

   Bruce Evans a accept ce patch, donc si une version plus rcente de
   BCC existe, le patch devrait avoir t intgr...

  Comme appeller l'assembleur?

   Voici l'entre d'un Makefile GNU pour utiliser bcc pour transformer un
   fichier assembleur .s  la fois en un objet a.out GNU .o et un listing
   .l:
     _________________________________________________________________

%.o %.l:        %.s
        bcc -3 -G -c -A-d -A-l -A$*.l -o $*.o $<
     _________________________________________________________________

   Supprimez %.l, -A-l, et -A$*.l, si vous ne voulez pas avoir de
   listing. Si vous souhaitez obtenir autre chose que du a.out GNU,
   consultez la documentation de bcc concernant les autres formats
   reconnus et/ou utilisez le programme objcopy du paquetage binutils.

  O trouver de la documentation

   Les documentations se trouvent dans le paquetage bcc. Des pages de
   manuel sont galement disponibles quelque part sur le site de FreeBSD.
   Dans le doute, les sources sont assez souvent une bonne documentation:
   ce n'est pas trs comment mais le style de programmation est trs
   simple. Vous pouvez essayer de voir comment as86 est utilis dans
   Tunes 0.0.0.25...

  Que faire si je ne peux plus compiler Linux avec cette nouvelleversion

   Linus est submerg par le courrier lectronique et mon patch pour
   compiler Linux avec un as86 a.out n'a pas d lui parvenir (!). Peu
   importe: conservez le as86 provenant du paquetage bin86 dans le
   rpertoire /usr/bin, et laissez bcc installer le bon as86 en tant que
   /usr/local/libexec/i386/bcc/as comme que de droit. Vous n'aurez jamais
   besoin d'appeler explicitement ce dernier, car bcc se charge trs bien
   de tout, y compris la conversion en a.out Linux, lorsqu'il est appel
   avec les bonnes options. Assemblez les fichiers uniquement en passant
   par bcc, et non pas en appelant as86 directement.

3.6 Autres assembleurs

   Il s'agit d'autres possibilits, qui sortent de la voie ordinaire,
   pour le cas o les solutions prcdentes ne vous conviennent pas (mais
   je voudrais bien savoir pourquoi?), que je ne recommande pas dans les
   cas habituels, mais qui peuvent se montrer fort utiles si l'assembleur
   doit faire partie intgrante du logiciel que vous concevez (par
   exemple un systme d'exploitation ou un environnement de
   dveloppement).

  L'assembleur de Win32Forth

   Win32Forth est un systme ANS FORTH 32 bit _libre_ qui fonctionne sous
   Win32s, Win95, Win/NT. Il comprend un assembleur 32 bit libre (sous
   forme prfixe ou postfixe) intgre au langage FORTH. Le traitement
   des macro est effectu en utilisant toute la puissance du langage
   rflexif FORTH. Toutefois, le seul contexte d'entre et sortie reconnu
   actuellement est Win32For lui-mme (aucune possibilit d'obtenir un
   fichier objet, mais vous pouvez toujours l'ajouter par vous-mme, bien
   sr). Vous pouvez trouver Win32For  l'adresse suivante:
   ftp://ftp.forth.org/pub/Forth/win32for/

  Terse

   Terse est un outil de programmation qui fournit _LA_ syntaxe
   assembleur la plus compacte pour la famille des processeur x86! Voir
   le site http://www.terse.com. Ce n'est cependant pas un logiciel
   libre. Il y aurait eu un clone libre quelque part, abandonn  la
   suite de mensongres allgations de droits sur la syntaxe, que je vous
   invite  ressusciter si la syntaxe vous intresse.

  Assembleurs non libres et/ou non 32 bits

   Vous trouverez un peu plus d'informations sur eux, ainsi que sur les
   bases de la programmation assembleur sur x86, dans la FAQ de Raymond
   Moon pour le forum comp.lang.asm.x86. Voir
   http://www2.dgsys.com/~raymoon/faq/asmfaq.zip

   Remarquez que tous les assembleurs DOS devraient fonctionner avec
   l'mulateur DOS de Linux ainsi qu'avec d'autres mulateurs du mme
   genre. Aussi, si vous en possdez un, vous pouvez toujours l'utiliser
    l'intrieur d'un vrai systme d'exploitation. Les assembleurs sous
   DOS assez rcents grent galement les formats de fichiers objets COFF
   et/ou des formats grs par la bibliothque GNU BFD de telle manire
   que vous pouvez les utiliser en conjonction avec les outils 32 bits
   libres, en utilisant le programme GNU objcopy (du paquetage binutils)
   comme un filtre de conversion.

4. Mta-programmation/macro-traitement

   La programmation en assembleur est particulirement pnible si ce
   n'est pour certaines parties critiques des programmes.

   Pour travail donn, il faut l'outil appropri; ne choisissez donc pas
   l'assembleur lorsqu'il ne correspond pas au problme  rsoudre: C,
   OCAML, perl, Scheme peuvent tre un meilleur choix dans la plupart des
   cas.

   Toutefois, il y a certains cas o ces outils n'ont pas un contrle
   suffisamment fin sur la machine, et o l'assembleur est utile ou
   ncessaire. Dans ces cas, vous apprcierez un systme de programmation
   par macros, ou un systme de mta-programmation, qui permet aux motifs
   rptitifs d'tre factoriss chacun en une seule dfinition
   indfiniment rutilisable. Cela permet une programmation plus sre,
   une propagation automatique des modifications desdits motifs, etc. Un
   assembleur de base souvent ne suffit pas, mme pour n'crire que de
   petites routines  lier  du code C.

4.1 Description

   Oui, je sais que cette partie peut manquer d'informations utiles 
   jour. Vous tes libres de me faire part des dcouvertes que vous
   auriez d faire  la dure...

  GCC

   GCC vous permet (et vous oblige) de spcifier les contraintes entre
   registres assembleurs et objets C, pour que le compilateur puisse
   interfacer le code assembleur avec le code produit par l'optimiseur.
   Le code assembleur en ligne est donc constitu de motifs, et pas
   forcment de code exact.

   Et puis, vous pouvez mettre du code assembleur dans des
   macro-dfinitions de CPP ou des fonctions "en-ligne" (inline), de
   telle manire que tout le monde puisse les utiliser comme n'importe
   quelle fonction ou macro C. Les fonctions en ligne ressemblent
   normment aux macros mais sont parfois plus propres  utiliser.
   Mfiez-vous car dans tous ces cas, le code sera dupliqu, et donc
   seules les tiquettes locales (comme 1:) devraient tre dfinies dans
   ce code assembleur. Toutefois, une macro devrait permettre de passer
   en paramtre le nom ventuellement ncessaire d'une tiquette dfinie
   non localement (ou sinon, utilisez des mthodes supplmentaires de
   mta-programmation). Notez galement que propager du code assembleur
   en-ligne rpandra les bogues potentiels qu'il contiendrait, aussi,
   faites doublement attention  donner  GCC des contraintes correctes.

   Enfin, le langage C lui-mme peut tre considr comme tant une bonne
   abstraction de la programmation assembleur, qui devrait vous viter la
   plupart des difficults de la programmation assembleur.

   Mfiez-vous des optimisations consistant  passer les arguments en
   utilisant les registres: cela interdit aux fonctions concernes d'tre
   appeles par des routines exterieurs (en particulier celles crites 
   la main en assembleur) d'une manire standard; l'attribut asmlinkage
   devrait empcher des routines donnes d'tre concernes par de telles
   options d'optimisation. Voir les sources du noyau Linux pour avoir des
   exemples.

  GAS

   GAS a quelques menues fonctionnalit pour les macro, dtailles dans
   la documentation TeXinfo. De plus

   J'ai entendu dire que les versions rcentes en seront dotes... voir
   les fichiers TeXinfo). De plus, tandis que GCC reconnat les fichiers
   en .s comme de l'assembleur  envoyer dans GAS, il reconnat aussi les
   fichiers en .S comme devant tre filtrer  travers CPP avant d'tre
   envoyer  GAS. Au risque de me rpter, je vous convie  consulter les
   sources du noyau Linux.

  GASP

   Il ajoute toutes les fonctionnalits habituelles de macro  GAS. Voir
   sa documentation sous forme texinfo.

  NASM

   NASM possde aussi son systme de macros. Consultez sa documentation.
   Si vous avez quelqu'ide lumineuse, contactez les auteurs, tant donn
   qu'ils sont en train de dvelopper NASM activement. Pendant ce mme
   temps, lisez la partie sur les filtres externes un peu plus loin.

  AS86

   Il possde un systme simple de macros, mais je n'ai pas pu trouver de
   documentation. Cependant, les sources sont d'une approche
   particulirement aise, donc si vous tes intress pour en savoir
   plus, vous devriez pouvoir les comprendre sans problme. Si vous avez
   besoin d'un peu plus que des bases, vous devriez utiliser un filtre
   externe (voir un peu plus loin).

  Autres assembleurs

     * Win32FORTH: CODE et END-CODE sont des macros qui ne basculent pas
       du mode interprtation au mode compilation; vous aurez donc accs
        toute la puissance du FORTH lors de l'assemblage.
     * Tunes: cela ne fonctionne pas encore, mais le langage Scheme est
       un langage de trs haut niveau qui permet une mta-programmation
       arbitraire.

4.2 Filtres externes

   Quelque soit la gestion des macros de votre assembleur, ou quelque
   soit le langage que vous utilisez (mme le C), si le langage n'est pas
   assez expressif pour vous, vous pouvez faire passer vos fichier 
   travers un filtre externe grce  une rgle comme suit dans votre
   Makefile:
     _________________________________________________________________

%.s:    %.S autres_dpendances
        $(FILTER) $(FILTER_OPTIONS) < $< > $@
     _________________________________________________________________

  CPP

   CPP n'est vraiment pas trs expressif, mais il suffit pour les choses
   faciles, et il est appel d'une manire transparente par GCC.

   Comme exemple de limitation, vous ne pouvez pas dclarer d'objet de
   faon  ce qu'un destructeur soit automatiquement appel  la fin du
   bloc ayant dclar l'objet. Vous n'avez pas de diversions ou de
   gestion de porte des variables, etc.

   CPP est livr avec tout compilateur C. Si vous pouvez faire sans,
   n'allez pas chercher CPP (bien que je me demande comment vous pouvez
   faire).

  M4

   M4 vous donne la pleine puissance du macro-traitement, avec un langage
   Turing-quivalent, rcursivit, expressions rgulires, etc. Vous
   pouvez faire avec tout ce que cpp ne peut faire.

   Voir macro4th/This4th que l'on trouve sur
   ftp://ftp.forth.org/pub/Forth/ dans Reviewed/ ANS/ (?), ou les sources
   de Tunes 0.0.0.25 comme exemple de programmation avance en utilisant
   m4.

   Toutefois, le systme de citation est trs pnible  utiliser et vous
   oblige  utiliser un style de programmation par fonctions rcursives
   avec passage explicite de continuation (CPS) pour toute programmation
   _avance_ (ce qui n'est pas sans rappeler  TeX -- au fait quelqu'un
   a-t-il dj essay d'utiliser TeX comme macro-processeur pour autre
   chose que de la mise-en-page?). Toutefois, ce n'est pas pire que cpp
   qui ne permet ni citation ni rcursivit.

   La bonne version de m4  rcuprer est GNU m4 1.4 (ou ultrieure si
   elle existe). C'est celle qui contient le plus de fonctionnalit et le
   moins de bogues ou de limitations. m4 est conu pour tre
   intrinsquement lent pour toute utilisation sauf la plus simple; cela
   suffit sans aucun doute pour la plupart des programmes en assembleur
   (vous n'allez quand mme pas crire des millions de lignes en
   assembleur, si?).

  Macro-traitement avec votre propre filtre

   Vous pouvez crire votre propre programme d'expansion de macro avec
   les outils courants comme perl, awk, sed, etc. C'est assez rapide 
   faire et vous pouvez tout contrler. Mais bien toute puissance dans le
   macro-traitement doit se gagner  la dure.

  Mta-programmation

   Plutt que d'utiliser un filtre externe qui effectue l'expansion des
   macros, une manire de raliser cela est d'crire des programmes qui
   crivent d'autres programmes, en partie ou en totalit.

   Par exemple, vous pourriez utiliser un programme gnrant du code
   source
     * pour crer des tables de sinus/cosinus (ou autre),
     * pour dcompiler un fichier binaire en source annot annot,
     * pour compiler vos bitmaps en des routines d'affichage rapides,
     * pour extraire de la documentation, du code d'initilisation ou
       finalisation, des tables de descriptions, aussi bien que du code
       normal depuis les mmes fichiers sources;
     * pour utiliser une technique spcifique de production de code,
       produite avec un script perl/shell/scheme
     * pour propager des donnes dfinies en une seule fois dans de
       nombreux morceaux de code ou tables avec rfrences croises.
     * etc.

   Pensez-y!

  Backends provenant de compilateur existants

   Des compilateurs comme SML/NJ, Objective CAML, MIT-Scheme, etc, ont
   leur propre gnrateur de code assembleur, que vous pouvez ou non
   utiliser, si vous souhaitez gnrer du code semi-automatiquement
   depuis les langages correspondants.

  Le New-Jersey Machine-Code Toolkit

   Il s'agit projet utilisant le langage de programmation Icon pour btir
   une base de code de manipulation d'assembleur. Voir
   http://www.cs.virginia.edu/~nr/toolkit/

  Tunes

   Le projet de systme d'exploitation OS dveloppe son propre assembleur
   comme tant une extension du langage Scheme. Il ne fonctionne pas
   encore totalement, de l'aide est bienvenue.

   L'assembleur manipule des arbres de syntaxes symboliques, de telle
   manire qu'il puisse servir comme base d'un traducteur de syntaxe
   assembleur, un dsassembleur, l'assembleur d'un compilateur, etc. Le
   fait qu'il utile un vrai langage de programmation puissant comme
   Scheme le rend imbatable pour le macro-traitement et pour la
   mta-programmation.

   http://www.eleves.ens.fr:8080/home/rideau/Tunes/

5. Conventions d'appel

5.1 Linux

  Edition de liens avec GCC

   C'est la solution la plus pratique. Consultez la documentation de gcc
   et prenez exemple sur les sources du noyau Linux (fichiers .S qui sont
   utiliss avec gas, non pas as86).

   Les arguments 32 bits sont empils dans la pile vers le bas dans
   l'ordre inverse de l'ordre syntaxique (c'est--dire qu'on accde aux
   arguments ou les dpile dans l'ordre syntaxique), au-dessus de
   l'adresse de retour 32 bits. %ebp, %esi, %edi, %ebx doivent tre
   conservs par l'appel, les autres registres peuvent tre dtruits;
   %eax doit contenir le rsultat, ou %edx:%eax pour des rsultats sur 64
   bits.

   Pile virgule flottante: je ne suis pas sr, mais je pense que le
   rsultat se trouve dans st(0), la pile tant  la discrtion de
   l'appel.

   Notez que GCC possde certaines options pour modifier les conventions
   d'appel en rservant certains registres, en mettant les arguments dans
   des registres, en supposant que l'on ne possde pas de FPU, etc.
   Consultez les pages .info concernant le i386.

   Il faut prendre garde  dclarer l'attribut cdecl pour une fonction
   qui suit la convention standard GCC (je ne sais pas exactement ce que
   cela produit avec des conventions modifies). Consultez la
   documentation GCC dans la section: C Extensions::Extended Asm::

  Problmes ELF et a.out

   Certains compilateurs C ajoutent un underscore avant tout symbole,
   alors que d'autres ne le font pas.

   En particulier, la version GCC a.out effectue ce genre d'ajouts, alors
   que la version ELF ne le fait pas.

   Si vous tes confront  ce problme, regardez comment des paquetages
   existants traitent le problmes. Par exemple, rcuprer une ancienne
   arborescence des sources de Linux, Elk, les qthreads ou OCAML...

   Vous pouvez galement redfinir le renommage implicite de C en
   assembleur en ajoutant les instructions suivantes:
     _________________________________________________________________

        void truc asm("machin") (void);
     _________________________________________________________________

   pour s'assurer que la fonction C truc sera rellement appele machin
   en assembleur.

   Remarquez que l'outil objcopy, du paquetage binutils, devrait vous
   permettre de transformer vos fichiers objets a.out en objets ELF et
   peut-tre inversement dans certains cas. D'une manire plus gnrale,
   il vous permet d'effectuer de nombreuses conversions de formats de
   fichiers.

  Appels systmes directs

   Il n'est absolument pas recommand d'effectuer de tels appels par ce
   que leurs conventions peuvent changer de temps en temps, ou d'un type
   de noyau  un autre (cf L4Linux), de plus, ce n'est pas portable,
   difficile  crire, redondant avec l'effort entrepris par libc, et
   enfin, cela empche les corrections et les extensions effectues 
   travers la libc, comme par exemple avec le programme zlibc qui ralise
   une dcompression  la vole de fichiers compresss avec gzip. La
   manire standard et recommende d'effectuer des appels systmes est et
   restera de passer par la libc.

   Les objets partags devraient rduire l'occupation mmoire des
   programmes, et si vous souhaitez absolument avoir de petits
   excutables, utilisez #! avec un interprteur qui contiendra tout ce
   que vous ne voulez pas mettre dans vos binaires.

   Maintenant, si pour certaines raisons, vous ne souhaitez pas effectuer
   une dition des liens avec la libc, rcuprez-la et essayez de
   comprendre comment elle fonctionne! Aprs tout, vous prtendez bien la
   remplacer non?

   Vous pouvez aussi regarder comment eforth 1.0c le fait.

   Les sources de Linux sont fort utiles, en particulier le fichier
   d'en-tte asm/unistd.h qui dcrit comment sont effectus les appels
   systme...

   Le principe gnral est d'utiliser l'instruction int $0x80 avec le
   numro de l'appel systme __NR_machin (regarder dans asm/unistd.h)
   dans %eax, et les paramtres (jusqu' cinq) dans %ebx, %ecx, %edx,
   %esi, %edi. Le rsultat est renvoy dans %eax avec un rsultat ngatif
   tant l'erreur dont l'oppos est tranfr par la libc dans errno. La
   pile utilisateur n'est pas modifice donc n'avez pas besoin d'en avoir
   une correcte lors de l'appel.

  Entres/sorties sous Linux

   Si vous souhaitez effectuer des entres/sorties directement sous
   Linux, soit il s'agit de quelque chose de trs simple qui n'a pas
   besoin de spcificits du systme et dans ce cas l, consultez le
   mini-HOWTO IO-Port-Programming, ou alors vous devez crer un nouveau
   gestionnaire de priphrique et vous devriez alors lire quelques
   documents sur les mandres du noyau, le dveloppement de gestionnaires
   de priphriques, les modules du noyau, etc. Vous trouverez
   d'excellents HOWTO ou autres documents du projet LDP.

   Plus particulirement, si vous souhaitez raliser des programmes
   graphiques, rejoignez le projet GGI: http://synergy.caltech.edu/~ggi/
   http://sunserver1.rz.uni-duesseldorf.de/~becka/doc/scrdrv.html

   Dans tous les cas, vous devriez plutt utiliser l'assembleur en ligne
   de GCC avec les macros provenant des fichiers linux/asm/*.h que
   d'crire des sources en assembleur pur.

  Accder aux gestionnaires 16 bits avec Linux/i386

   De telles choses sont thoriquement possibles (preuve: voir comment
   DOSEMU permet  des programmes d'accder au port srie), et j'ai
   entendu des rumeurs que certaines personnes le font (avec le
   gestionnaire PCI? Accs aux cartes VESA? PnP ISA? Je ne sais pas). Si
   vous avez de plus amples prcisions  ce sujet, soyez les bienvenus.
   Le bon endroit  regarder est les sources du noyau, les sources de
   DOSEMU (et des autres programmes se trouvant dans le rpertoire
   DOSEMU), ainsi que les sources d'autres programmes bas niveaux
   (peut-tre GGI s'il gre les cartes VESA).

   En fait, vous devez utiliser soit le mode protg 16 bits, soit le
   mode vm86.

   Le premier est plus simple  configurer mais il ne fonctionne qu'avec
   du code ayant un comportement propre qui n'effectue pas d'arithmtique
   de segments ou d'adressage absolu de segment (en particulier pour
   l'adressage du segment 0),  moins que par chance tous les segments
   utiliss peuvent tre configur  l'avance dans le LDT.

   La seconde possiblit permet d'tre plus "compatibles" avec les
   environnements 16 bits mais il ncessite une gestion bien plus
   complique.

   Dans les deux cas, avant de sauter sur le code 16 bits, vous devez:
     * mmapper toute adresse absolue utilise dans le code 16 bits (comme
       la ROM, les tampons vido, les adresses DMA et les entres/sorties
       passant des zones de mmoires mappes)  partir de /dev/mem dans
       votre espace d'adressage de votre processus.
     * configurer le LDT et/ou le moniteur en mode vm86.
     * demander au noyau les droits d'accs ncessaires pour les
       entres/sorties (voir plus haut).

   Encore une fois, lisez attentivement les codes sources situs dans le
   rpertoire de DOSEMU et consorts, en particulier ces mini-mulateurs
   permettant de faire tourner des programmes ELKS et/ou des .COM assez
   simples sous Linux/i386.

5.2 DOS

   La plupart des mulateurs DOS sont livrs avec certaines interfaces
   d'accs aux services DOS. Lisez leur documentation  ce sujet, mais
   bien souvent, ils ne font que simuler int $0x21 et ainsi de suite,
   donc c'est comme si vous tiez en mode rel (je doute qu'ils aient de
   possibilits de fonctionner avec des oprandes 32 bits: ils ne font
   que rflchir l'interruption dans le mode rel ou dans le gestionnaire
   vm86).

   Certaines documentations concernant DPMI (ou ses variantes peuvent)
   tre trouves sur ftp://x2ftp.oulu.fi/pub/msdos/programming/

   DJGPP est livr avec son propre sous-ensemble, driv, ou remplacement
   (limit) de la glibc.

   Il est possible d'effectuer une compilation croise de Linux vers DOS.
   Consultez le rpertoire devel/msdos/ de votre miroir FTP de
   sunsite.unc.edu. Voir galement le dos-extender MOSS du projet Flux
   d'utah.

   D'autres documentations et FAQ sont plus consacrs  DOS. Nous
   dconseillons le dveloppement sous DOS.

5.3 Windauberies...

   Heu, ce document ne traite que de libre logiciel. Tlphonez-moi
   lorsque Windaube le deviendra ou du moins ses outils de dveloppement!

   En fait, aprs tout, cela existe: Cygnus Solutions a dvelopp la
   bibliothque cygwin32.dll pour que les programmes GNU puissent
   fonctionner sur les machines MicroMerdiques. Donc, vous pouvez
   utiliser GCC, GAS et tous les outils GNU ainsi que bon nombre
   d'applications Unix. Consultez leur site Web. Je (Far) ne souhaite
   pas m'tendre sur la programmation sous Windaube, mais je suis sr que
   vous trouverez tout un tas d'informations partout...

5.4 Votre propre systme d'exploitation

   Le contrle sur le systme tant ce qui attire de nombreux
   programmeurs vers l'assembleur, une prmisse ou un corollaire naturel
   de son utilisation est la volont de dvelopper son propre systme
   d'exploitation. Remarquons tout d'abord que tout systme permettant
   son auto-dveloppement pourrait tre qualifi de systme
   d'exploitation, combien mme tournerait-il au-dessus d'un autre
   systme sur lequel il se dchargerait de la gestion du multitche
   (Linux sur Mach) ou des entres/sorties (OpenGenera sur Digital Unix),
   etc. Donc, pour simplifier le dbogage, vous pouvez souhaiter
   dvelopper votre systme d'exploitation comme tant un processus
   fonctionnant sous Linux (au prix d'un certain ralentissement), puis,
   utiliser le Flux OS kit (qui permet l'utilisation des drivers Linux et
   BSD dans votre propre systme d'exploitation) pour le rendre
   indpendant. Lorsque votre systme est stable, il est toujours temps
   d'crire vos propres gestionnaires de matriels si c'est vraiment
   votre passion.

   Ce HowTo ne couvrira pas des sujets comme le code de chargement du
   systme, le passage en mode 32 bits, la gestion des interruptions, les
   bases concernant les horreurs des processeurs Intel (mode protg,
   V86/R86), la dfinition de votre format d'objets ou de vos conventions
   d'appel. L'endroit o vous pourrez trouver le plus d'informations
   concernant tous ces sujets est le code source de systme dj
   existants.

   Un grand nombre de pointeurs se trouvent dans la page:
   http://www.eleves.ens.fr:8080/home/rideau/Tunes/Review/OSes.html

6. A faire et pointeurs

     * complter les sections incompltes;
     * ajouter des pointeurs sur des programmes et des documentations;
     * ajouter des exemples de tous les jours pour illustrer la syntaxe,
       la puissance et les limitation de chacune des solutions proposes;
     * demander aux gens de me donner un coup de main;
     * trouver quelqu'un qui a assez de temps pour prendre en charge la
       maintenance de ce HOWTO;
     * peut-tre dire quelques mots sur l'assembleur d'autres
       plates-formes?
     * Quelques pointeurs (en plus de ceux qui se trouvent dans ce
       document)
          + pages de manuel pour pentium
          + hornet.eng.ufl.edu pour les codages assembleurs
          + ftp.luth.se
          + PM FAQ
          + Page Assembleur 80x86
          + Courseware
          + programmation de jeux
          + experiences de programmation sous Linux exclusivement en
            assembleur
     * Et bien sur, utilisez vos outils habituels de recherche sur
       Internet pour trouver les informations. Merci de m'envoyer tout ce
       que vous trouvez d'interessant.

   Signature de l'auteur:
--    ,                                         ,           _ v    ~  ^  --
--
-- Fare -- rideau@clipper.ens.fr -- Francois-Rene Rideau -- +)ang-Vu Ban --
--                                      '                   / .          --
Join the TUNES project for a computing system based on computing freedom!
                 TUNES is a Useful, Not Expedient System
WWW page at URL: http://www.eleves.ens.fr:8080/home/rideau/Tunes/
