Assembly HOWTO
 Francois-Rene Rideau [email protected]
 v0.4l, 16 Novembre 1997

 (Version   francaise   realisee   par   Eric   Dumas  [email protected]
 [email protected], et Fare Rideau [email protected], 11  Novembre  1997).
 Ce document decrit comment programmer en assembleur x86 en n'utilisant
 que des outils de developpement _l_i_b_r_e_s, et tout particulierement  avec
 le systeme d'exploitation Linux sur la plate-forme i386.  Les informa-
 tions contenues dans ce  document  peuvent  etre  applicables  ou  non
 applicables  a d'autres plates-formes materielles ou logicielles.  Les
 contributions a ce documents seront acceptees avec  gratitude.   _m_o_t_s_-
 _c_l_e_f_s:  assembleur, libre, macroprocesseur, preprocesseur, asm, inline
 asm, 32 bits, x86, i386, gas, as86, nasm

 11..  IInnttrroodduuccttiioonn

 11..11..  CCooppyyrriigghhtt

 Copyright (c) 1996,1997 Francois-Rene Rideau.  Ce document  peut  etre
 redistribue   sous  les  termes  de  la  license  LDP,  disponibles  a
 <http://sunsite.unc.edu/LDP/COPYRIGHT.html>.

 11..22..  NNoottee iimmppoorrttaannttee

 Ceci est cense etre la derniere version que j'ecrirai de ce  document.
 Il  y a un candidat pour reprendre en charge le document, mais jusqu'a
 ce qu'il le  reprenne  completement  en  main,  je  serai  heureux  de
 m'occuper de tout courrier concernant ce document.

 Vous  etes  tout  specialement  invites  a  poser  des  questions, a y
 repondre, a corriger les donnees, a ajouter de nouvelles informations,
 a  completer  les  references  sur  d'autres  logiciels,  a  mettre en
 evidence les erreurs et lacunes du document.  Si  vous  etes  motives,
 vous  pouvez  meme pprreennddrree eenn cchhaarrggee ccee ddooccuummeenntt.  En un mot, apporter
 votre contribution!

 Pour contribuer a ce document,  contactez  la  personne  qui  apparait
 actuellement en charge.  Au moment ou j'ecris ces lignes, il s'agit de
 Francois-Rene Rideau <mailto:[email protected]>) ainsi que de Paul
 Anderson <mailto:[email protected]>.

 11..33..  AAvvaanntt--PPrrooppooss

 Ce  document est destine a repondre aux questions les plus frequemment
 posees par les gens qui developpent ou qui souhaitent  developper  des
 programmes  en  assembleurs  x86  32  bits  en utilisant des logiciels
 _l_i_b_r_e_s,  et  tout  particulierement  sous  Linux.   Vous  y  trouverez
 egalement  des  liens  sur  d'autres  documents traitant d'assembleur,
 fondes sur des outils logiciels qui ne sont pas libres, pas 32-bit, ou
 pas  dedies  a  l'architecture  x86,  bien que cela ne soit pas le but
 principal de ce document.

 Etant donne que l'interet principal de la programmation en  assembleur
 est    d'etablir    les   fondations   de   systemes   d'exploitation,
 d'interpreteurs, de compilateurs, et de jeux, la ou un  compilateur  C
 n'arrive  plus  a  fournir  le  pouvoir  d'expression  necessaire (les
 performances etant  de  plus  en  plus  rarement  un  probleme),  nous
 insisteront sur le developpement de tels logiciels.

 11..33..11..  CCoommmmeenntt uuttiilliisseerr ccee ddooccuummeenntt

 Ce  document  contient  des  reponses a un certain nombre de questions
 frequemment posees.  Des URL y sont donnes, qui pointent sur des sites
 contenant  documents  ou  logiciels.   Prenez  conscience que les plus
 utiles de ces sites sont dupliques sur des serveurs miroirs, et  qu'en
 utilisant le site miroir le plus proche de chez vous, vous evitez a un
 gachis inutile aussi bien de precieuses ressources reseau  communes  a
 l'Internet  que  de  votre  propre temps.  Ainsi, il existe un certain
 nombre de gros serveurs dissemines sur la planete, qui  effectuent  la
 duplication  d'autres  sites  importants.  Cherchez ou se trouvent ces
 sites et identifiez les plus proches de chez vous (du point de vue  du
 reseau).  Parfois, la liste des miroirs est donnees dans un fichier ou
 dans  le  message  de  connexion.  Suivez  ces   conseils.    Si   ces
 informations ne sont pas presentes, utilisez le programme archie.

 La version la plus recente de ce document peut etre trouvee 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 repertoires de HowTo Linux _d_e_v_r_a_i_e_n_t normalement etre  a  peu
 pres a jour (je ne peux pas le garentir):

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

 La version francaise de ce document peut etre trouvee sur le site

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

 11..33..22..  AAuuttrreess ddooccuummeennttss ddee rreeffeerreennccee

 +o  si  vous ne savez ce qu'est le _l_i_b_r_e logiciel, lisez avec attention
    la GPL (GNU General Public License), qui est utilisee 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 generalement dans un fichier nomme COPYING, avec une
    version pour les bibliotheques de routines dans  un  fichier  nomme
    COPYING.LIB.    Les  ecrits  publies  par  la  FSF  (free  software
    foundation) peuvent egalement vous aider a comprendre le phenomene.

 +o  plus  precisement,  les  logiciels  libres  interessants  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.

 +o  il existe une FAQ dans le forum de discussion comp.lang.asm.x86 qui
    repond  aux  questions  generales  concernant  la  programmation en
    assembleur  pour  x86,  et  aux   questions   concernant   certains
    assembleurs   commerciaux   dans  un  environnement  DOS  16  bits.
    Certaines de ces reponses peuvent s'appliquer a la programmation 32
    bits, aussi serez-vous sans-doute interesses de lire cette FAQ...

    <http://www2.dgsys.com/~raymoon/faq/asmfaq.zip>

 +o  Sont  disponibles  des  FAQs,  de la documentation, et des sources,
    concernant  la  programmation  sur  votre   plate-forme   preferee,
    quelqu'elle  soit, et vous devriez les consulter pour les problemes
    lies a votre plate-forme  qui  ne  seraient  pas  specifique  a  la
    programmation en assembleur.

 11..44..  HHiissttoorriiqquuee ddee ddooccuummeenntt

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

    VVeerrssiioonn 00..11     2233 AAvvrriill 11999966
       Francois-Rene "Fare"  Rideau  <[email protected]>  cree  et  diffuse
       initialement  le  document  sous  forme d'un mini-HOWTO car ``Je
       suis un peu fatigue d'avoir a repondre encore  et  toujours  aux
       memes questions dans le forum comp.lang.asm.x86''

    VVeerrssiioonn 00..22       44 MMaaii 11999966
       *

    VVeerrssiioonn 00..33cc      1155 JJuuiinn 11999966
       *

    VVeerrssiioonn 00..33ff    1177 OOccttoobbrree 11999966
       Tim  Potter indique l'option -fasm pour activer l'assembleur en-
       ligne de GCC sans le reste des optimisations de -O.

    VVeerrssiioonn 00..33gg    22 NNoovveemmbbrree 11999966
       Creation de l'historique. Ajout de pointeurs dans la section sur
       la  compilation  croisee.  Ajout  d'une  section  concernant  la
       programmation des entrees/sorties  sous  Linux  (en  particulier
       pour l'acces video).

    VVeerrssiioonn 00..33hh    66 NNoovveemmbbrree 11999966
       plus sur la compilation croisee - voir sur sunsite: devel/msdos/

    VVeerrssiioonn 00..33ii    1166 NNoovveemmbbrree 11999966
       NASM commence a etre particulierement interessant

    VVeerrssiioonn 00..33jj    2244 NNoovveemmbbrree 11999966
       Reference sur la version francaise

    VVeerrssiioonn 00..33kk    1199 DDeecceemmbbrree 11999966
       Quoi? J'avais oublie de parler de Terse?

    VVeerrssiioonn 00..33ll    1111 JJaannvviieerr 11999977
       *

    VVeerrssiioonn 00..44pprree11 1133 JJaannvviieerr 11999977
       Le mini-HOWTO au format texte est transforme en  un  authentique
       HOWTO  au  format  linuxdoc-sgml, pour explorer les possibilites
       dudit format.

    VVeerrssiioonn 00..44     2200 JJaannvviieerr 11999977
       Premiere diffusion de ce HOWTO.

    VVeerrssiioonn 00..44aa    2200 JJaannvviieerr 11999977
       Ajout de la section CREDITS

    VVeerrssiioonn 00..44bb    33 FFeevvrriieerr 11999977
       NASM mis avant AS86

    VVeerrssiioonn 00..44cc    99 FFeevvrriieerr 11999977
       Ajout   de   la   partie   "Avez-vous    besoin    d'utilisateur
       l'assembleur?"

    VVeerrssiioonn 00..44dd      2288 FFeevvrriieerr 11999977
       Annonce fantome d'un nouveau responsable de ce HowTo.

    VVeerrssiioonn 00..44ee      1133 MMaarr 11999977
       Version diffusee pour DrLinux

    VVeerrssiioonn 00..44ff      2200 MMaarrss 11999977
       *

    VVeerrssiioonn 00..44gg      3300 MMaarrss 11999977
       *

    VVeerrssiioonn 00..44hh      1199 JJuuiinn 11999977
       Ajouts a propos de "Comment ne pas utiliser l'assembleur"; mises
       a jour concernant NASM et GAS.

    VVeerrssiioonn 00..44ii      1177 JJuuiilllleett 11999977
       Informations sur l'acces au mode 16 bits a partir de Linux.

    VVeerrssiioonn 00..44jj      77 SSeepptteemmbbeerr 11999977
       *

    VVeerrssiioonn 00..44kk      1199 OOccttoobbrree 11999977
       je (Fare) reprends en main la traduction francaise du HowTo

    VVeerrssiioonn 00..44ll      1166 NNoovveemmbbrree 11999977
       version pour LSL 6eme edition.

       Il  s'agit  encore  d'une  nouvelle  ``toute  derniere   version
       realisee  par  Fare avant qu'un nouveau responsable ne prenne la
       main''.

 11..55..  CCrreeddiittss

 Je souhaiterais remercier les personnes suivantes:

 +o  Linus Torvalds <mailto:[email protected]> pour Linux

 +o  Bruce Evans <mailto:[email protected]> pour bcc d'ou as86 est extrait

 +o  Simon    Tatham    <mailto:[email protected]>   et   Julian   Hall
    <mailto:[email protected]> pour NASM.

 +o  Jim Neil <mailto:[email protected]> pour Terse

 +o  Greg Hankins <mailto:[email protected]>  pour  la  coordination
    des HOWTOs

 +o  Raymond Moon <mailto:[email protected]> pour sa FAQ

 +o  Eric  Dumas <mailto:[email protected]> pour la traduction initiale
    en francais...  (l'auteur, francais, est  le  premier  attriste  de
    devoir ecrire l'original en anglais)

 +o  Paul  Anderson  <mailto:[email protected]>  et  Rahim Azizarab
    <mailto:[email protected]>  pour  m'avoir  aide,   a   defaut   de
    reprendre le HowTo en main.

 +o  toutes les personnes qui ont contribue a l'ecriture de ce document,
    par leurs idees, remarques ou leur soutient moral.

 22..  AAvveezz--vvoouuss bbeessooiinn ddee ll''aasssseemmbblleeuurr??

 Je ne veux en aucun cas jouer les empecheurs-de-tourner-en-rond,  mais
 voici quelques conseils issus d'une experience gagnee a la dure.

 22..11..  LLee PPoouurr eett llee CCoonnttrree

 22..11..11..  LLeess aavvaannttaaggeess ddee ll''aasssseemmbblleeuurr

 L'assembleur  peut  vous permettre de realiser des operations tres bas
 niveau:

 +o  vous pouvez acceder aux registres et  aux  ports  d'entrees/sorties
    specifiques a votre machine;

 +o  vous pouvez parfaitement controler le comportemant du code dans des
    sections critiques  ou  pourraient  sinon  advenir  un  blocage  du
    processeur ou des peripheriques;

 +o  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  regles
    d'allocation memoire, gerer manuellement le cours  de  l'execution,
    etc.);

 +o  acceder  a  des  modes  de  programmation  non  courants  de  votre
    processeur  (par  exemple  du  code  16  bits  pour  l'amorcage  ou
    l'interfacage avec le BIOS, sur les peces Intel);

 +o  vous  pouvez construire des interfaces entre des fragments de codes
    utilisant des conventions incompatibles (c'est-a-dire  produit  par
    des  compilateurs  differents  ou  separes  par  une interface bas-
    niveau);

 +o  vous  pouvez  generer  un  code  assez  rapide  pour  les   boucles
    importantes  pour  pallier aux defauts d'un compilateur qui ne sait
    les optimiser (mais bon, il existe des  compilateurs  optimisateurs
    librement disponibles!);

 +o  vous  pouvez  generer  du  code  optimise  "a la main" qui est plus
    parfaitement regle pour  votre  configuration  materielle  precise,
    meme s'il ne l'est pour aucune autre configuration;

 +o  vous  pouvez  ecrire  du  code  pour le compilateur optimisateur de
    votre nouveau langage.  (c'est la une activite a  laquelle  peu  se
    livrent, et encore, rarement.)

 22..11..22..  LLeess iinnccoonnvveenniieennttss ddee ll''aasssseemmbblleeuurr

 L'assembleur  est  un  langage tres bas niveau (le langage du plus bas
 niveau qui soit au dessus du codage a la main de motifs d'instructions
 en binaire). En consequence:

 +o  l'ecriture de code en est longue et ennuyeuse;

 +o  les bogues apparaissent aisement;

 +o  les bogues sont difficiles a reperer et supprimer;

 +o  il  est  difficile  de  comprendre  et  de  modifier  du  code  (la
    maintenance est tres compliquee);

 +o  le  resultat  est  extremement  peu   portable   vers   une   autre
    architecture, existante ou future;

 +o  votre  code  ne sera optimise que une certaine implementation d'une
    meme  architecture:  ainsi,  parmi  les  plates-formes  compatibles
    Intel,  chaque  realisation  d'un  processeur  et  de ses variantes
    (largeur   du   bus,    vitesse    et    taille    relatives    des
    CPU/caches/RAM/Bus/disques,   presence  ou  non  d'un  coprocesseur
    arithmetique,  et  d'extensions  MMX  ou   autres)   implique   des
    techniques d'optimisations parfois radicalement differentes.  Ainsi
    different  grandement  les  processeurs  deja  existant  et   leurs
    variations:  Intel 386, 486, Pentium, PPro, Pentium II; Cyrix 5x86,
    6x86; AMD K5, K6.  Et ce n'est surement pas  termine:  de  nouveaux
    modeles  apparaissent  continuellement,  et  cette  liste meme sera
    rapidement depassee, sans parler du code ``optimise'' qui aura  ete
    ecrit pour l'un quelconque des processeurs ci-dessus.

 +o  le  code  peut  egalement  ne  pas  etre  portable entre differents
    systemes  d'exploitation  sur  la  meme  architecture,  par  manque
    d'outils  adaptes  (GAS  semble  fonctionner sur toutes les plates-
    formes; NASM semble fonctionner ou etre  facilement  adaptable  sur
    toutes les plates-formes compatibles Intel);

 +o  un  temps  incroyable  de  programmation  sera  perdu  sur de menus
    details, plutot que d'etre efficacement utilise pour la  conception
    et  le  choix des algorithmes utilises, alors que ces derniers sont
    connus pour etre la source  de  la  majeure  partie  des  gains  en
    vitesse  d'un  programme.   Par  exemple,  un grand temps peut etre
    passe a grapiller quelques cycles en ecrivant des routines  rapides
    de  manipulation  de chaines ou de listes, alors qu'un remplacement
    de la structure de  donnees  a  un  haut  niveau,  par  des  arbres
    equilibres  et/ou des tables de hachage permettraient immediatement
    un grand gain en vitesse, et une parallelisation  aisee,  de  facon
    portable permettant un entretien facile.

 +o  une  petite  modification  dans  la  conception  algorithmique d'un
    programme aneantit la validite du  code  assembleur  si  patiemment
    elabore,  reduisant  les  developpeurs  au  dilemne de sacrifier le
    fruit  de  leur  labeur,  ou  de  s'enchainer  a   une   conception
    algorithmique obsolete.

 +o  pour des programmes qui fait des choses non point trop eloignees de
    ce que font les benchmarks standards, les  compilateurs/optimiseurs
    commerciaux  produisent  du code plus rapide que le code assembleur
    ecrit a 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).

 +o  Quoi qu'il en soit, ains le dit le saige John Levine, moderateur de
    comp.compilers, "les compilateurs rendent  aisee  l'utilisation  de
    structures  de  donnees  complexes;  ils  ne  s'arretent pas, morts
    d'ennui, a mi-chemin du travail, et produisent du code  de  qualite
    tout  a  fait satisfaisante".  Ils permettent egalement de propager
    _c_o_r_r_e_c_t_e_m_e_n_t les transformations du code a  travers  l'ensemble  du
    programme,  aussi  henaurme  soit-il,  et peuvent optimiser le code
    par-dela les frontieres entre procedures ou entre modules.

 22..11..33..  AAffffiirrmmaattiioonn

 En pesant le pour et le contre, on peut conclure que  si  l'assembleur
 est  parfois  necessaire, et peut meme etre utile dans certains cas ou
 il ne l'est pas, il vaut mieux:

 +o  minimiser l'utilisation de code ecrit en assembleur;

 +o  encapsuler ce code dans des interfaces bien definies;

 +o  engendrer automatiquement le code assembleur  a  partir  de  motifs
    ecrits  dans  un  langage plus de haut niveau que l'assembleur (par
    exemple, des macros contenant de l'assembleur en-ligne, avec GCC);

 +o  utiliser des outils automatiques pour transformer ces programmes en
    code assembleur;

 +o  faire en sorte que le code soit optimise, si possible;

 +o  utiliser  toutes les techniques precedentes a la fois, c'est-a-dire
    ecrire ou etendre la passe d'optimisation d'un compilateur.

 Meme dans les cas ou l'assembleur est necessaire (par exemple lors  de
 developpement d'un systeme d'exploitation), ce n'est qu'a petite dose,
 et sans infirmer les principes ci-dessus.

 Consultez a 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 systeme d'exploitation  rapide,  fiable,  portable  et  d'entretien
 facile.   Meme  un jeu tres celebre comme DOOM a ete en sa plus grande
 partie ecrit en C,  avec  une  toute  petite  routine  d'affichage  en
 assembleur pour accelerer un peu.

 22..22..  CCoommmmeenntt nnee ppaass uuttiilliisseerr ll''aasssseemmbblleeuurr

 22..22..11..  MMeetthhooddee ggeenneerraallee ppoouurr oobbtteenniirr dduu ccooddee eeffffiiccaaccee

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

 ``L'homme devrait toujours gagner, et voici pourquoi:

 +o  Premierement, l'homme ecrit tout dans un langage de haut nivrau.

 +o  Deuxiemement, il mesure  les  temps  d'execution  (profiling)  pour
    determiner  les endroits ou le programme passe la majeure partie du
    temps.

 +o  Troisiemement,  il  demande  au  compilateur  d'engendrer  le  code
    assembleur produit pour ces petites sections de code.

 +o  Enfin,  il  effectue  a  la  main  modifications  et reglages, a la
    recherche des petites ameliorations possibles par rapport  au  code
    engendre par la machine.

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

 22..22..22..  LLaannggaaggeess aavveecc ddeess ccoommppiillaatteeuurrss ooppttiimmiissaatteeuurrss

 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,  meme  pour des boucles serrees, tout en vous permettant de
 vous concentrer sur des details haut niveau, et sans vous interdire de
 gagner  par  la  methode  precedente quelques pourcents de performance
 supplementaire, une fois la phase  de  conception  generale  terminee.
 Bien sur, il existe egalement des compilateurs optimiseurs commerciaux
 pour la plupart de ces langages.

 Certains langages ont des compilateurs qui produisent du  code  C  qui
 peut  ensuite  etre  optimise  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 a fait satisfaisante.

 22..22..33..  PPrroocceedduurree ggeenneerraallee aa ssuuiivvrree ppoouurr aacccceelleerreerr vvoottrree ccooddee

 Pour accelerer votre code, vous ne devriez traiter  que  les  portions
 d'un  programme  qu'un outil de mesure de temps d'execution (profiler)
 aura  identifie  comme  etant  un  goulot   d'etranglement   pour   la
 performance de votre programme.

 Ainsi,  si  vous identifiez une partie du code comme etant trop lente,
 vous devriez

 +o  d'abord essayer d'utiliser un meilleur algorithme;

 +o  essayer de la compiler au lieu de l'interpreter;

 +o  essayer  d'activer  les  bonnes  options  d'optimisation  de  votre
    compilateur;

 +o  donner  au  compilateur des indices d'optimisation (declarations de
    typage en LISP; utilisation des extensions GNU avec GCC; la plupart
    des compilos fourmillent d'options);

 +o  enfin  de compte seulement, se mettre a l'assembleur si necessaire.

 Enfin,  avant  d'en  venir  a  cette  derniere  option,  vous  devriez
 inspecter   le  code  genere  pour  verifier  que  le  probleme  vient
 effectivement d'une mauvaise generation de code, car il se  peut  fort
 bien  que  ce  ne  soit pas le cas: le code produit par le compilateur
 pourrait etre meilleur que celui que vous auriez ecrit, en particulier
 sur  les architectures modernes a pipelines multiples!  Il se peut que
 les portions les plus lentes de  votre  programme  le  soit  pour  des
 raisons  intrinseques.   Les plus gros problemes sur les architectures
 modernes a processeur rapide sont dues aux delais introduits  par  les
 acces   memoires,   manques   des  caches  et  TLB,  fautes  de  page;
 l'optimisation des registres devient vaine, et il vaut mieux  repenser
 les  structures de donnees et l'enchainement des routines pour obtenir
 une meilleur localite des  acces  memoire.   Il  est  possible  qu'une
 approche completement differente du probleme soit alors utile.

 22..22..44..  IInnssppeeccttiioonn dduu ccooddee pprroodduuiitt ppaarr llee ccoommppiillaatteeuurr

 Il  existe  de  nombreuses  raisons  pour  vouloir  regarder  le  code
 assembleur produit par le compilateur. Voici ce que vous pourrez faire
 avec ce code:

 +o  verifier si le code produit peut ou non etre ameliorer avec du code
    assembleur ecrit a la main (ou par un reglage different des options
    du compilateur);

 +o  quand  c'est  le  cas,  commencer  a partir de code automatiquement
    engendre et le modifier plutot que de repartir de zero;

 +o  plus generalement, utilisez le code  produit  comme  des  scions  a
    greffer,  ce  qui  a  tout  le  moins  vous  laisse  permet d'avoir
    gratuitement tout le code d'interfacage avec le monde exterieur.

 +o  reperer des bogues eventuels dus au compilateur lui-meme (esperons-
    le tres rare, quitte a se restreindre a des versions ``stables'' du
    compilo).

 La maniere standard d'obtenir le code assembleur genere 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 a vous  de
 voir  dans  votre cas.  Pour ce qui est de GCC, il produira un code un
 peu plus comprehensible avec l'option -fverbose-asm. Bien sur, si vous
 souhaitez obtenir du code assembleur optimise, n'oubliez pas d'ajouter
 les options et indices d'optimisation appropriees!

 33..  AAsssseemmbblleeuurrss

 33..11..  AAsssseemmbblleeuurr eenn--lliiggnnee ddee GGCCCC

 Le celebre GNU C/C++  Compiler  (GCC),  est  un  compilateur  32  bits
 optimisant  situe  au  coeur  du  projet  GNU.  Il gere assez bien les
 architectures x86 et permet d'inserer du code assembleur a l'interieur
 de  programmes C de telle maniere que les registres puissent etre soit
 specifies soit laisse aux bons soins de GCC.  GCC  fonctionne  sur  la
 plupart  des  plates-formes  dont Linux, *BSD, VSTa, OS/2, *DOS, Win*,
 etc.

 33..11..11..  OOuu ttrroouuvveerr GGCCCC

 Le  site  principal  de  GCC  est  le  site   FTP   du   projet   GNU:
 <ftp://prep.ai.mit.edu/pub/gnu/>  On  y  trouve  egalement  toutes les
 applications provenant du projet GNU.   Des  versions  configurees  ou
 precompilees       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 developpement de GCC s'est recemment scinde en deux; pour
 plus   d'informations   sur   la  version  experimentale,  egcs,  voir
 <http://www.cygnus.com/egcs/>

 Les sources adaptes a votre systeme d'exploitation prefere  ainsi  que
 les  binaires  precompiles  peuvent  etre  trouves  sur  les sites FTP
 courants.
 Le portage le plus celebre de GCC pour DOS est DJGPP et il  peut  etre
 trouve dans le repertoire du meme nom sur les sites ftp.  Voir:

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

 Il  existe  egalement  un  portage  de  GCC  pour  OS/2 appele EMX qui
 fonctionne egalement sous DOS et inclut un grand  nombre  de  routines
 d'emulation 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/>

 33..11..22..   OOuu ttrroouuvveerr ddee llaa ddooccuummeennttaattiioonn ssuurr ll''aasssseemmbblleeuurr eenn lliiggnnee aavveecc
 GGCCCC??

 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  a  peu  pres  n'importe
 quel  format  (avec  les  outils  adequats).   Les fichiers .info sont
 generalement installes en meme temps que GCC.

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

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

 Le site "DJGPP Games  resource"  (qui  n'est  pas  reserve  aux  seuls
 developpeurs de jeux) possede une page particuliere sur l'assembleur:

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

 Enfin,  il  existe  une  page  de  la  Toile  appelee "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  a  GAS  et  suit  donc  sa
 syntaxe  (voir plus bas), cela implique que l'assembleur en ligne doit
 utiliser des caracteres pourcents entre apostrophes pour qu'ils soient
 passes a GAS. Voir la section dediee a GAS.

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

 33..11..33..  AAppppeelllleerr GGCCCC ppoouurr oobbtteenniirr dduu ccooddee  aasssseemmbblleeuurr  eenn  lliiggnnee  ccoorr--
 rreeccttee??

 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
 faites  pas,  votre  code  pourra  compiler  mais  ne  pas  s'executer
 correctement!!       En      fait     (merci     a     Tim     Potter,
 [email protected]),  il  suffit  d'utiliser   l'option   -fasm,
 faisant partie de toutes les fonctionnalites activees par l'option -O.
 Donc si vous avez des problemes en raison d'optimisations boguees dans
 votre   implementation   de   gcc,   vous   pouvez  toujours  utiliser
 l'assembleur en ligne.   De  meme,  utilisez  l'option  -fno-asm  pour
 desactiver l'assembleur en ligne (on peut se demander pourquoi?).

 Plus  generalement,  les bonnes options de compilation a 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  superieures
 generent  un  code  un  peu  plus important, mais tres legerement plus
 rapide. De telles sur-optimisations peuvent etre utiles  que  dans  le
 cas  d'optimisations  de  boucles que vous pouvez toujours realiser en
 assembleur.  Si vous avez besoin de faire ce genre de  choses,  ne  le
 faites que pour les routines qui en ont besoin.

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

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

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

 Pour optimiser encore plus, vous pouvez utiliser l'option  -mregparm=2
 et/ou  les  attributs  de fonctions qui peuvent etre utilises mais ils
 peuvent  dans  certains  cas  poser  de  nombreux  problemes  lors  de
 l'edition  de  liens avec du code externe (notamment les bibliotheques
 partagees)...

 Notez que vous pouvez ajoutez ces options aux  options  utilisees  par
 defaut   sur   votre  systeme  en  editant  le  fichier  /usr/lib/gcc-
 lib/i486-linux/2.7.2.3/specs (cependant, ne rajoutez pas -Wall  a  ces
 options).

 33..22..  GGAASS

 GAS est l'assembleur GNU, utilise par gcc.

 33..22..11..  OOuu llee ttrroouuvveerr??

 Au meme endroit ou vous avez trouve gcc, dans le paquetage binutils.

 33..22..22..  QQuu''eesstt--ccee qquuee llaa ssyynnttaaxxee AATT&&TT

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

 Voici les points les plus importants a propos de la syntaxe de GAS:

 +o  Les noms de registres sont  prefixes  avec  %,  de  facon  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 necessite de prefixes _.

 +o  L'ordre   des  operandes  est  source(s)  d'abord,  destination  en
    dernier, a l'oppose de la convention d'intel consistant a mettre la
    destination  en  premier,  les source(s) ensuite.  Ainsi, ce qui en
    syntaxe intel  s'ecrit  mov  ax,dx  (affecter  au  registre  ax  le
    contentu du registre dx) s'ecrira en syntaxe att mov %dx, %ax.

 +o  La  longueur  des  operandes  est  specifiee  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 du  etre  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 etre
    devinee  grace  aux operandes qui sont des registres, la taille par
    defaut etant 32 bit (avec une mise en garde quand on y fait appel).

 +o  Les  operandes  immediates  sont marques d'un prefixe $, comme dans
    addl $5,%eax (ajouter la valeur  longue  immediate  5  au  registre
    %eax).

 +o  L'absence  de  prefixe  a une operande indique une adresse memoire;
    ainsi movl $foo,%eax met l'_a_d_r_e_s_s_e  de  la  variable  foo  dans  le
    registre  %eax,  tandis  que  movl  foo,%eax  met  le contenu de la
    variable foo dans le registre %eax.

 +o  L'indexation ou l'indirection se fait en mettant entre  parentheses
    le  registre  d'index  ou  la case memoire contenant l'indirection,
    comme dans testb $0x80,17(%ebp) (tester le bit  de  poids  fort  de
    l'octet au deplacement 17 apres la case pointee par %ebp).

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

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

 GAS possede une documentation complete  au  format  TeXinfo,  qui  est
 distribuee  entre  autre  avec les sources.  Vous pouvez parcourir les
 pages .info qui en sont extraites avec Emacs.  Il  y  avait  aussi  un
 fichier  nomme gas.doc ou as.doc disponible autour des sources de GAS,
 mais il a ete fusionne avec la documentation TeXinfo.   Bien  sur,  en
 cas  de  doute,  l'ultime documentation est constituee par les sources
 eux-memes!  Une section  qui  vous  interessera  particulierement  est
 Machine Dependencies::i386-Dependent::

 Les  sources de Linux dont un bon exemple: regardez dans le repertoire
 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 generer a 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 debut de ce document.

 33..22..33..  mmooddee 1166 bbiittss lliimmiittee

 GAS est un assembleur 32 bits, concu pour assembler  le  code  produit
 par  un compilateur 32 bits.  Il ne reconnait que d'une maniere limite
 le mode 16 bits  du  i386,  en  ajoutant  des  prefixes  32  bits  aux
 instructions;  vous  ecrivez  donc  en  realite  du  code 32 bits, qui
 s'execute en mode 16 bits sur un processeur 32 bits.   Dans  les  deux
 modes,  il  gere  les registres 16 bits, mais pas l'adressage 16 bits.
 Utilisez les instructions .code16 et .code32 pour basculer d'un mode a
 l'autre.  Notez que l'instruction assembleur en ligne asm(".code16\n")
 autorisera gcc a generer du code 32  bits  qui  fonctionnera  en  mode
 reel!

 Le code necessaire pour que GAS gere le mode 16 bits aurait ete ajoute
 par Bryan Ford (a confirmer?). Toutefois, ce code n'est  present  dans
 aucune distribution de GAS que j'ai essayee (jusqu'a binutils-2.8.1.x)
 ...  plus d'informations a ce sujet seraient les  bienvenues  dans  ce
 HowTo.

 Une  solution bon marche pour inserer quelques instructions 16-bit non
 reconnues pas GAS consiste a definir 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 precedement decrit, et pouvez
 vous permettre de supposer que le code fonctionnera sur un  processeur
 32  bits). Pour obtenir le systeme de codage correct, vous pouvez vous
 inspirer des assembleurs 16 bits.

 33..33..  GGAASSPP

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

 33..33..11..  OOuu ttrroouuvveerr ggaasspp??

 gasp est livre avec gas dans le paquetage binutils GNU.

 33..33..22..  CCoommmmeenntt iill ffoonnccttiioonnnnee??

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

 33..44..  NNAASSMM

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

 33..44..11..  OOuu ttrroouuvveerr NNAASSMM??

 <http://www.cryogen.com/Nasm>

 Les versions binaires se trouvent sur votre  miroir  sunsite  habituel
 dans   le  repertoire  devel/lang/asm/.   Il  devrait  egalement  etre
 disponible sous forme d'archive .rpm ou .deb parmi les contributions a
 votre distribution preferee RedHat ou Debian.

 33..44..22..  SSoonn rroollee

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

 La syntaxe est a la Intel.  Une gestion de macros est integree.

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

 NASM peut etre utilisee comme assembleur  pour  le  compilateur  libre
 LCC.

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

 Note: NASM est egalement livre avec un desassembleur, NDISASM.

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

 33..55..  AASS8866

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

 33..55..11..  WWhheerree ttoo ggeett AASS8866

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

 Les versions les plus recentes de Bruce  Evans  ([email protected])  est
 diffusee  avec  la  distribution  FreeBSD.  Enfin, elles l'etaient! 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 (egalement  appele  ELKS)  s'est  d'une  certaine
 maniere  chargee  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 recentes, a la difference de
 celle de HJLu, gerent le format  a.out  de  Linux;  vous  pouvez  donc
 effectuer  des  editions  de  liens  avec  des programmes Linux, et/ou
 utiliser les outils habituels provenant  du  paquetage  binutils  pour
 manipuler  vos  donnees.   Cette version peut co-exister sans probleme
 avec les versions precedentes (voir la question a ce sujet un peu plus
 loin).

 La  version  du  12  mars  1995  de BCC ainsi que les precedentes a un
 probleme  qui  provoque  la  generation  de  toutes   les   operations
 d'empilement/depilement   de   segments   en   16  bits,  ce  qui  est
 particulierement ennuyant lorsque vous developpez en mode 32 bits.  Un
 patch est diffuse par le projet Tunes

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

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

 Le patch peut egalement etre directement recupere sur

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

 Bruce Evans a accepte ce patch, donc si une version  plus  recente  de
 BCC existe, le patch devrait avoir ete integre...

 33..55..22..  CCoommmmee aappppeelllleerr ll''aasssseemmbblleeuurr??

 Voici l'entree d'un Makefile GNU pour utiliser bcc pour transformer un
 fichier assembleur .s a 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\*(dR*.l -o \*(dR*.o \*(dR<
 ______________________________________________________________________

 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.

 33..55..33..  OOuu ttrroouuvveerr ddee llaa ddooccuummeennttaattiioonn

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

 33..55..44..  vveerrssiioonn QQuuee ffaaiirree ssii jjee nnee ppeeuuxx pplluuss ccoommppiilleerr LLiinnuuxx aavveecc cceettttee
 nnoouuvveellllee

 Linus  est  submerge  par  le  courrier electronique et mon patch pour
 compiler Linux avec un as86 a.out n'a pas du lui  parvenir  (!).   Peu
 importe:  conservez  le  as86  provenant  du  paquetage  bin86 dans le
 repertoire /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
 tres  bien  de tout, y compris la conversion en a.out Linux, lorsqu'il
 est appele avec les bonnes options.  Assemblez les fichiers uniquement
 en passant par bcc, et non pas en appelant as86 directement.

 33..66..  AAuuttrreess aasssseemmbblleeuurrss

 Il  s'agit  d'autres  possibilites,  qui sortent de la voie ordinaire,
 pour le cas ou les solutions precedentes 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  integrante  du  logiciel  que  vous concevez (par
 exemple   un   systeme   d'exploitation   ou   un   environnement   de
 developpement).

 33..66..11..  LL''aasssseemmbblleeuurr ddee WWiinn3322FFoorrtthh

 Win32Forth  est  un systeme ANS FORTH 32 bit _l_i_b_r_e qui fonctionne sous
 Win32s, Win95, Win/NT.  Il comprend un assembleur 32 bit  libre  (sous
 forme  prefixe  ou postfixe) integree au langage FORTH.  Le traitement
 des macro est effectue en utilisant  toute  la  puissance  du  langage
 reflexif  FORTH.   Toutefois,  le  seul  contexte  d'entree  et sortie
 reconnu  actuellement  est  Win32For  lui-meme   (aucune   possibilite
 d'obtenir  un  fichier  objet, mais vous pouvez toujours l'ajouter par
 vous-meme, bien  sur).   Vous  pouvez  trouver  Win32For  a  l'adresse
 suivante: <ftp://ftp.forth.org/pub/Forth/win32for/>

 33..66..22..  TTeerrssee

 Terse  est un outil de programmation qui fournit _L_A 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,  abandonne  a  la  suite  de
 mensongeres allegations de droits sur la syntaxe, que je vous invite a
 ressusciter si la syntaxe vous interesse.

 33..66..33..  AAsssseemmbblleeuurrss nnoonn lliibbrreess eett//oouu nnoonn 3322 bbiittss

 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'emulateur DOS de Linux ainsi qu'avec  d'autres  emulateurs  du  meme
 genre.  Aussi, si vous en possedez un, vous pouvez toujours l'utiliser
 a l'interieur d'un vrai systeme d'exploitation.  Les assembleurs  sous
 DOS assez recents gerent egalement les formats de fichiers objets COFF
 et/ou des formats geres par la bibliotheque GNU BFD de  telle  maniere
 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.

 44..  MMeettaa--pprrooggrraammmmaattiioonn//mmaaccrroo--ttrraaiitteemmeenntt

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

 Pour travail donne, il faut l'outil approprie; ne choisissez donc  pas
 l'assembleur  lorsqu'il  ne  correspond pas au probleme a resoudre: C,
 OCAML, perl, Scheme peuvent etre un meilleur choix dans la plupart des
 cas.

 Toutefois,  il  y  a  certains cas ou ces outils n'ont pas un controle
 suffisamment fin sur la machine,  et  ou  l'assembleur  est  utile  ou
 necessaire.    Dans   ces   cas,   vous   apprecierez  un  systeme  de
 programmation par macros, ou un  systeme  de  meta-programmation,  qui
 permet  aux  motifs  repetitifs  d'etre factorises chacun en une seule
 definition indefiniment reutilisable.  Cela permet  une  programmation
 plus  sure,  une  propagation  automatique  des  modifications desdits
 motifs, etc.  Un assembleur de base souvent ne suffit pas,  meme  pour
 n'ecrire que de petites routines a lier a du code C.

 44..11..  DDeessccrriippttiioonn

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

 44..11..11..  GGCCCC

 GCC  vous  permet  (et vous oblige) de specifier 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  constitue  de  motifs,  et  pas
 forcement de code exact.

 Et  puis,  vous  pouvez  mettre  du  code  assembleur  dans des macro-
 definitions de CPP ou des  fonctions  "en-ligne"  (inline),  de  telle
 maniere  que  tout le monde puisse les utiliser comme n'importe quelle
 fonction ou macro C.  Les fonctions en  ligne  ressemblent  enormement
 aux macros mais sont parfois plus propres a utiliser.  Mefiez-vous car
 dans tous  ces  cas,  le  code  sera  duplique,  et  donc  seules  les
 etiquettes  locales  (comme  1:)  devraient etre definies dans ce code
 assembleur. Toutefois,  une  macro  devrait  permettre  de  passer  en
 parametre le nom eventuellement necessaire d'une etiquette definie non
 localement (ou sinon, utilisez des methodes supplementaires  de  meta-
 programmation).   Notez  egalement que propager du code assembleur en-
 ligne repandra les bogues potentiels qu'il contiendrait, aussi, faites
 doublement attention a donner a GCC des contraintes correctes.

 Enfin, le langage C lui-meme peut etre considere comme etant une bonne
 abstraction de la programmation assembleur, qui devrait vous eviter la
 plupart des difficultes de la programmation assembleur.

 Mefiez-vous  des  optimisations  consistant  a passer les arguments en
 utilisant les registres: cela interdit aux fonctions concernees d'etre
 appelees  par des routines exterieurs (en particulier celles ecrites a
 la main en assembleur) d'une maniere standard;  l'attribut  asmlinkage
 devrait  empecher des routines donnees d'etre concernees par de telles
 options d'optimisation.  Voir les sources du noyau  Linux  pour  avoir
 des exemples.

 44..11..22..  GGAASS

 GAS  a  quelques menues fonctionnalite pour les macro, detaillees dans
 la documentation TeXinfo.  De plus

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

 44..11..33..  GGAASSPP

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

 44..11..44..  NNAASSMM

 NASM possede aussi son systeme de macros.  Consultez sa documentation.
 Si vous avez quelqu'idee lumineuse, contactez les auteurs, etant donne
 qu'ils sont en train de developper NASM activement.  Pendant  ce  meme
 temps, lisez la partie sur les filtres externes un peu plus loin.

 44..11..55..  AASS8866

 Il possede un systeme simple de macros, mais je n'ai pas pu trouver de
 documentation.    Cependant,   les   sources   sont   d'une   approche
 particulierement  aisee,  donc  si  vous etes interesse pour en savoir
 plus, vous devriez pouvoir les comprendre sans probleme.  Si vous avez
 besoin  d'un  peu  plus que des bases, vous devriez utiliser un filtre
 externe (voir un peu plus loin).

 44..11..66..  AAuuttrreess aasssseemmbblleeuurrss

 +o  Win32FORTH: CODE et END-CODE sont des macros qui ne  basculent  pas
    du mode interpretation au mode compilation; vous aurez donc acces a
    toute la puissance du FORTH lors de l'assemblage.

 +o  Tunes: cela ne fonctionne pas encore, mais le langage Scheme est un
    langage  de  tres  haut  niveau  qui  permet une meta-programmation
    arbitraire.

 44..22..  FFiillttrreess eexxtteerrnneess

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

 ______________________________________________________________________
 %.s:    %.S autres_dependances
         \*(dR(FILTER) \*(dR(FILTER_OPTIONS) < \*(dR< > \*(dR@
 ______________________________________________________________________

 44..22..11..  CCPPPP

 CPP n'est vraiment pas tres expressif, mais il suffit pour les  choses
 faciles, et il est appele d'une maniere transparente par GCC.

 Comme  exemple  de  limitation, vous ne pouvez pas declarer d'objet de
 facon a ce qu'un destructeur soit automatiquement appele a la  fin  du
 bloc  ayant  declare  l'objet.  Vous  n'avez  pas  de diversions ou de
 gestion de portee des variables, etc.

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

 44..22..22..  MM44

 M4 vous donne la pleine puissance du macro-traitement, avec un langage
 Turing-equivalent,  recursivite,  expressions  regulieres,  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  avancee  en
 utilisant m4.

 Toutefois,  le systeme de citation est tres penible a utiliser et vous
 oblige a utiliser un style de programmation par  fonctions  recursives
 avec  passage explicite de continuation (CPS) pour toute programmation
 _a_v_a_n_c_e_e (ce qui n'est pas sans rappeler a TeX -- au fait quelqu'un  a-
 t-il  deja  essaye  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 recursivite.

 La  bonne  version  de m4 a recuperer est GNU m4 1.4 (ou ulterieure si
 elle existe).  C'est celle qui contient le plus de  fonctionnalite  et
 le  moins  de  bogues  ou  de  limitations.   m4  est  concu pour etre
 intrinsequement lent pour toute utilisation sauf la plus simple;  cela
 suffit  sans  aucun doute pour la plupart des programmes en assembleur
 (vous n'allez  quand  meme  pas  ecrire  des  millions  de  lignes  en
 assembleur, si?).

 44..22..33..  MMaaccrroo--ttrraaiitteemmeenntt aavveecc vvoottrree pprroopprree ffiillttrree

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

 44..22..44..  MMeettaa--pprrooggrraammmmaattiioonn

 Plutot que d'utiliser un filtre externe qui effectue  l'expansion  des
 macros,  une  maniere de realiser cela est d'ecrire des programmes qui
 ecrivent d'autres programmes, en partie ou en totalite.

 Par exemple, vous pourriez utiliser  un  programme  generant  du  code
 source

 +o  pour creer des tables de sinus/cosinus (ou autre),

 +o  pour decompiler un fichier binaire en source annote annote,

 +o  pour compiler vos bitmaps en des routines d'affichage rapides,

 +o  pour  extraire  de  la  documentation,  du  code d'initilisation ou
    finalisation, des tables de descriptions, aussi bien  que  du  code
    normal depuis les memes fichiers sources;

 +o  pour  utiliser  une  technique  specifique  de  production de code,
    produite avec un script perl/shell/scheme

 +o  pour propager des donnees  definies  en  une  seule  fois  dans  de
    nombreux morceaux de code ou tables avec references croisees.

 +o  etc.

 Pensez-y!

 44..22..44..11..  BBaacckkeennddss pprroovveennaanntt ddee ccoommppiillaatteeuurr eexxiissttaannttss

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

 44..22..44..22..  LLee NNeeww--JJeerrsseeyy MMaacchhiinnee--CCooddee TToooollkkiitt

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

 44..22..44..33..  TTuunneess

 Le projet de systeme d'exploitation OS developpe son propre assembleur
 comme  etant  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
 maniere  qu'il  puisse  servir  comme  base d'un traducteur de syntaxe
 assembleur, un desassembleur, 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  meta-
 programmation.

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

 55..  CCoonnvveennttiioonnss dd''aappppeell

 55..11..  LLiinnuuxx

 55..11..11..  EEddiittiioonn ddee lliieennss aavveecc GGCCCC

 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
 utilises avec gas, non pas as86).

 Les  arguments  32  bits  sont  empiles  dans la pile vers le bas dans
 l'ordre inverse de l'ordre syntaxique (c'est-a-dire qu'on  accede  aux
 arguments  ou  les  depile  dans  l'ordre  syntaxique),  au-dessus  de
 l'adresse de retour 32 bits.  %ebp,  %esi,  %edi,  %ebx  doivent  etre
 conserves  par  l'appele,  les autres registres peuvent etre detruits;
 %eax doit contenir le resultat, ou %edx:%eax pour des resultats sur 64
 bits.

 Pile  virgule  flottante:  je  ne  suis  pas sur, mais je pense que le
 resultat se trouve dans st(0),  la  pile  etant  a  la  discretion  de
 l'appele.

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

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

 55..11..22..  PPrroobblleemmeess EELLFF eett aa..oouutt

 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 etes confronte a ce probleme, regardez comment des paquetages
 existants traitent le problemes. Par exemple, recuperer  une  ancienne
 arborescence des sources de Linux, Elk, les qthreads ou OCAML...

 Vous  pouvez  egalement  redefinir  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 reellement  appelee  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-etre inversement dans certains cas.  D'une maniere plus generale,
 il vous permet d'effectuer de nombreuses  conversions  de  formats  de
 fichiers.

 55..11..33..  AAppppeellss ssyysstteemmeess ddiirreeccttss

 Il  n'est  absolument pas recommande d'effectuer de tels appels par ce
 que leurs conventions peuvent changer de temps en temps, ou d'un  type
 de  noyau  a  un  autre  (cf L4Linux), de plus, ce n'est pas portable,
 difficile a ecrire, redondant avec l'effort  entrepris  par  libc,  et
 enfin,  cela  empeche  les  corrections et les extensions effectuees a
 travers la libc, comme par exemple avec le programme zlibc qui realise
 une  decompression  a  la  volee de fichiers compresses avec gzip.  La
 maniere standard et recommendee d'effectuer des appels systemes est et
 restera de passer par la libc.

 Les   objets  partages  devraient  reduire  l'occupation  memoire  des
 programmes,  et  si  vous  souhaitez  absolument   avoir   de   petits
 executables,  utilisez  #! avec un interpreteur qui contiendra tout ce
 que vous ne voulez pas mettre dans vos binaires.

 Maintenant, si pour certaines raisons, vous ne souhaitez pas effectuer
 une  edition  des  liens  avec  la  libc,  recuperez-la  et essayez de
 comprendre comment elle fonctionne! Apres tout, vous pretendez bien la
 remplacer non?
 Vous     pouvez     aussi     regarder     comment     eforth     1.0c
 <ftp://ftp.forth.org/pub/Forth/Linux/linux-eforth-1.0c.tgz> le fait.

 Les sources de Linux sont fort utiles, en particulier le fichier d'en-
 tete  asm/unistd.h  qui  decrit  comment  sont  effectues  les  appels
 systeme...

 Le principe general est d'utiliser l'instruction  int  $0x80  avec  le
 numero  de  l'appel  systeme  __NR_machin (regarder dans asm/unistd.h)
 dans %eax, et les parametres (jusqu'a cinq)  dans  %ebx,  %ecx,  %edx,
 %esi, %edi. Le resultat est renvoye dans %eax avec un resultat negatif
 etant l'erreur dont l'oppose est tranfere par la libc dans  errno.  La
 pile utilisateur n'est pas modificee donc n'avez pas besoin d'en avoir
 une correcte lors de l'appel.

 55..11..44..  EEnnttrreeeess//ssoorrttiieess ssoouuss LLiinnuuxx

 Si vous  souhaitez  effectuer  des  entrees/sorties  directement  sous
 Linux,  soit  il  s'agit  de  quelque chose de tres simple qui n'a pas
 besoin de specificites du systeme et dans  ce  cas  la,  consultez  le
 mini-HOWTO  IO-Port-Programming,  ou alors vous devez creer un nouveau
 gestionnaire de peripherique  et  vous  devriez  alors  lire  quelques
 documents sur les meandres du noyau, le developpement de gestionnaires
 de  peripheriques,  les  modules  du  noyau,   etc.   Vous   trouverez
 d'excellents HOWTO ou autres documents du projet LDP.

 Plus  particulierement,  si  vous  souhaitez  realiser  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 plutot utiliser l'assembleur en  ligne
 de  GCC  avec  les  macros  provenant  des  fichiers linux/asm/*.h que
 d'ecrire des sources en assembleur pur.

 55..11..55..  AAcccceeddeerr aauuxx ggeessttiioonnnnaaiirreess 1166 bbiittss aavveecc LLiinnuuxx//ii338866

 De telles choses sont theoriquement possibles  (preuve:  voir  comment
 DOSEMU  permet  a  des  programmes  d'acceder  au port serie), et j'ai
 entendu  des  rumeurs  que  certaines  personnes  le  font  (avec   le
 gestionnaire  PCI? Acces aux cartes VESA? PnP ISA? Je ne sais pas). Si
 vous avez de plus amples precisions a ce sujet, soyez  les  bienvenus.
 Le  bon  endroit  a  regarder est les sources du noyau, les sources de
 DOSEMU (et des autres programmes se trouvant dans le repertoire DOSEMU
 <ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/>), ainsi que les sources
 d'autres programmes bas niveaux (peut-etre GGI s'il  gere  les  cartes
 VESA).

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

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

 La seconde  possiblite  permet  d'etre  plus  "compatibles"  avec  les
 environnements  16  bits  mais  il  necessite  une  gestion  bien plus
 compliquee.
 Dans les deux cas, avant de sauter sur le code 16 bits, vous devez:

 +o  mmapper toute adresse absolue utilisee dans le code 16 bits  (comme
    la  ROM, les tampons video, les adresses DMA et les entrees/sorties
    passant des zones de memoires mappees) a partir  de  /dev/mem  dans
    votre espace d'adressage de votre processus.

 +o  configurer le LDT et/ou le moniteur en mode vm86.

 +o  demander   au   noyau  les  droits  d'acces  necessaires  pour  les
    entrees/sorties (voir plus haut).

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

 55..22..  DDOOSS

 La  plupart  des  emulateurs DOS sont livres avec certaines interfaces
 d'acces aux services DOS. Lisez leur documentation a  ce  sujet,  mais
 bien  souvent,  ils  ne  font que simuler int $0x21 et ainsi de suite,
 donc c'est comme si vous etiez en mode reel (je doute qu'ils aient  de
 possibilites  de  fonctionner  avec des operandes 32 bits: ils ne font
 que reflechir l'interruption dans le mode reel ou dans le gestionnaire
 vm86).

 Certaines  documentations  concernant  DPMI (ou ses variantes peuvent)
 etre trouvees sur <ftp://x2ftp.oulu.fi/pub/msdos/programming/>

 DJGPP est livre avec son propre sous-ensemble, derive, ou remplacement
 (limite) de la glibc.

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

 D'autres documentations et  FAQ  sont  plus  consacres  a  DOS.   Nous
 deconseillons le developpement sous DOS.

 55..33..  WWiinnddaauubbeerriieess......

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

 En    fait,    apres    tout,    cela    existe:    Cygnus   Solutions
 <http://www.cygnus.com> a developpe la bibliotheque 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 (Fare) ne souhaite pas m'etendre  sur  la  programmation
 sous  Windaube,  mais  je  suis  sur  que  vous  trouverez tout un tas
 d'informations partout...

 55..44..  VVoottrree pprroopprree ssyysstteemmee dd''eexxppllooiittaattiioonn

 Le  controle  sur  le  systeme  etant  ce  qui  attire   de   nombreux
 programmeurs  vers l'assembleur, une premisse ou un corollaire naturel
 de son utilisation est la volonte de  developper  son  propre  systeme
 d'exploitation.   Remarquons  tout d'abord que tout systeme permettant
 son   auto-developpement   pourrait   etre   qualifie    de    systeme
 d'exploitation,   combien  meme  tournerait-il  au-dessus  d'un  autre
 systeme sur lequel il se dechargerait  de  la  gestion  du  multitache
 (Linux sur Mach) ou des entrees/sorties (OpenGenera sur Digital Unix),
 etc.   Donc,  pour  simplifier  le  debogage,  vous  pouvez  souhaiter
 developper  votre  systeme  d'exploitation  comme  etant  un processus
 fonctionnant sous Linux (au prix d'un certain  ralentissement),  puis,
 utiliser  le  Flux  OS kit <http://ww.cs.utah.edu/projects/flux/> (qui
 permet l'utilisation des  drivers  Linux  et  BSD  dans  votre  propre
 systeme  d'exploitation)  pour  le  rendre independant.  Lorsque votre
 systeme est  stable,  il  est  toujours  temps  d'ecrire  vos  propres
 gestionnaires de materiels si c'est vraiment votre passion.

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

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

 66..  AA ffaaiirree eett ppooiinntteeuurrss

 +o  completer les sections incompletes;

 +o  ajouter des pointeurs sur des programmes et des documentations;

 +o  ajouter des exemples de tous les jours pour illustrer  la  syntaxe,
    la puissance et les limitation de chacune des solutions proposees;

 +o  demander aux gens de me donner un coup de main;

 +o  trouver  quelqu'un  qui  a assez de temps pour prendre en charge la
    maintenance de ce HOWTO;

 +o  peut-etre dire quelques  mots  sur  l'assembleur  d'autres  plates-
    formes?

 +o  Quelques  pointeurs  (en  plus  de  ceux  qui  se  trouvent dans ce
    document)

 +o  pages          de           manuel           pour           pentium
    <http://www.intel.com/design/pentium/manuals/>

 +o  hornet.eng.ufl.edu      pour      les      codages      assembleurs
    <http://www.eng.ufl.edu/ftp>

 +o  ftp.luth.se <ftp://ftp.luth.se/pub/msdos/demos/code/>

 +o  PM FAQ <ftp://zfja-gate.fuw.edu.pl/cpu/protect.mod>

 +o  Page Assembleur 80x86 <http://www.fys.ruu.nl/~faber/Amain.html>

 +o  Courseware <http://www.cit.ac.nz/smac/csware.htm>

 +o  programmation                        de                        jeux
    <http://www.ee.ucl.ac.uk/~phart/gameprog.html>

 +o  experiences  de  programmation  sous  Linux        exclusivement en
    assembleur <http://bewoner.dma.be/JanW>

 +o  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 -- [email protected] -- 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/