<!doctype linuxdoc system>

<!--NOTE PER GLI EDITORI:

Vengono lasciate quelle in inglese, che vanno considerate come ufficiali.
In seguito viene fornita una traduzione non ufficiale.

	(1) This document uses iso-8859-1 latin encoding,
	so you must give -l flag to sgmltools

	(2) some of the material here can be skipped for a paper print,
	in as much as it is redundant with other material
	(e.g. how to use the HOWTO, plea for contributions, etc,
	which should be replaced by a generic explanation at the head
	of any good HOWTO compendium),
	or not worth the paper needed to print it
	(HISTORY&CREDITS in the introduction, .sig at the end),
	considering that HOWTO compendiums must squeeze lots of
	stuff on a limited place.

        (3) I recommend that you should not edit/remove/strip
	the rest of the document (after the introduction and before the footer)
	unless you explicitly state you did on the same page
	as the HOWTO appears, and/or you agree with me before.

	(4) if you print my .sig, then beware that the way it
	should appear is as it appears in the text version of the
	Assembly-HOWTO, whereas LaTeX is likely to get confused by
	meta-caracters not well quoted by sgml2latex.

Traduzione (non ufficiale - fare riferimento alla versione originale):

        (1) Questo documento utilizza la codifica iso-8859-1 latin,
        perci&ograve; dovete usare il flag -l con gli sgmtools

        (2) parte del materiale in questo documento puo` essere omesso
        per una stampa su carta, in quanto ridondante rispetto ad altro
        materiale (ad esempio, come usare questo HOWTO, richieste di
        contributi, ed altre cose che dovrebbero essere rimpiazzate da una
        spiegazione generica al principio di ogni buona raccolta di HOWTO)
        oppure di scarso valore (storia e ringraziamenti nell'introduzione,
        .sig alla fine), visto che le raccolte di HOWTO devono condensare
        un mucchio di roba in uno spazio limitato.

        (3) consiglio di non modificare/rimuovere/sfrondare il resto
        del docunmento (dopo l'introduzione e prima della signature
        a meno che non lo dichiariate esplicitamente nella stessa pagina
        in cui compare l'HOWTO, e/o vi siate accordati con me.

        (4) se stampate la mia .sig, fate attenzione che il modo in cui
        dovrebbe apparire è quello in cui compare nella versione
        testuale dell'Assembly-HOWTO, mentre è facile che LaTeX venga
        confuso da metacaratteri che sgml2latex non ben protetto
        dall'espansione.
-->


<article OPTS="italian">

<title>Assembly HOWTO
<author>François-René Rideau <tt>rideau@ens.fr</tt>
<date>v0.4l, 16 Novembre 1997

<abstract>
Questo &egrave; il
Linux Assembly HOWTO.

Questo documento descrive come programmare in assembly
utilizzando strumenti di programmazione <em>LIBERI</em>,
concentrandosi sullo sviluppo per o sul sistema operativo Linux
su piattaforme i386.

Il materiale incluso potrebbe essere o meno applicabile
ad altre piattaforme hardware e/o software.
Contributi riguardo a queste sarebbero ben accetti.

<em>parole chiave</em>:
	assembly, assembler, libero, macro, preprocessore,
	asm, inline, 32-bit, x86, i386, gas, as86, nasm.

Traduzione di Matteo De Luigi (giotto@maya.dei.unipd.it).

</abstract>

<toc>

<sect>INTRODUZIONE

<sect1>Legal Blurp
<p>
Copyright &copy; 1996,1997 by François-René Rideau.
This document may be distributed under the terms set forth in the LDP license
at <url url="http://sunsite.unc.edu/LDP/COPYRIGHT.html">.

<sect1>NOTA IMPORTANTE
<p>
C'&egrave; da aspettarsi che questo sia l'ultimo rilascio di questo documento
da parte mia.

C'&egrave; un candidato al ruolo di curatore,
ma finch&eacute; l'HOWTO non diventa ufficialmente suo, accetter&ograve;
suggerimenti e critiche.

   Siete in particolare invitati
a porre domande,
a rispondere alle domande,
a correggere le risposte date,
ad aggiungere nuove risposte alle FAQ,
a fornire riferimenti ad altro software,
ad indicare errori o lacune nelle pagine al responsabile attuale.
Se qualcuno di voi &egrave; motivato, potrebbe perfino
<em/DIVENTARE IL RESPONSABILE DELLE FAQ/.
   In una parola, contribuite!

   Per contribuire, per favore contattate chiunque sembri
curare l'Assembly-HOWTO.
I curatori attuali sono:
<url url="mailto:rideau@clipper.ens.fr" name="François-René Rideau">
ed ora
<url url="mailto:paul@geeky1.ebtech.net" name="Paul Anderson">.
<!-- Rahim Azizarab (rahim@megsinet.net) si era offerto volontario,
	ma da allora non si &egrave; pi&ugrave; fatto sentire -->


<sect1>Prima di cominciare
<p>
Questo documento intende rispondere alle domande pi&ugrave; frequenti delle
persone che programmano o vogliono programmare in assembly a 32 bit per x86
utilizzando assemblatori <em/liberi/, specialmente sotto il sistema operativo
Linux.
Potrebbe inoltre rimandare ad altri documenti circa assemblatori non liberi,
non per x86 o non a 32 bit, anche se questo non &egrave; il
suo scopo principale.

Poich&eacute; l'interesse principale della programmazione in assembly
consiste nel realizzare le viscere dei sistemi operativi, degli
interpreti, dei compilatori e dei giochi, laddove un compilatore C non
riesce a fornire l'espressivit&agrave; richiesta (&egrave; abbastanza raro che
si tratti di una questione di prestazioni), ci interesseremo principalmente
di questo tipo di software.


<sect2>Come usare questo documento
<p>
Questo documento contiene risposte ad alcune domande poste di frequente.
In molte occasioni, vengono forniti URL di alcuni archivi di software
o documentazione.
Per favore, notate che gli archivi di maggiore utilit&agrave; hanno dei
mirror e che accedendo ad un mirror pi&ugrave; vicino da un lato
evitate ad Internet traffico non necessario e
dall'altro risparmiate tempo prezioso.
In particolare, ci sono dei grandi depositi sparsi per tutto il mondo
che fanno il mirror anche di altri archivi di pubblico interesse.

Dovreste imparare ad annotarvi quali sono questi posti vicino a voi
(dal punto di vista della rete).

Talvolta, la lista dei mirror si trova in un file
o in un messaggio di login. Siete pregati di seguire i consigli. 
Altrimenti, dovreste interrogare archie circa il software di cui siete
alla ricerca...

La versione pi&ugrave; recente di questi documenti risiede ad

	<url url="http://www.eleves.ens.fr:8080/home/rideau/Assembly-HOWTO">
	oppure
	<url url="http://www.eleves.ens.fr:8080/home/rideau/Assembly-HOWTO.sgml">

ma anche ci&ograve; che si trova negli archivi degli HOWTO di Linux
<em/dovrebbe/ essere abbastanza aggiornato
(io non ho modo di saperlo):

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

Una traduzione in francese di questo HOWTO pu&ograve; essere trovata dalle parti di:

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


<sect2>Documenti correlati
<p>
<itemize>

<item>Se non sapete cos'&egrave; il software <em/libero/,
siete pregati di leggere <em/attentamente/ la Licenza Pubblica Generale GNU,
che viene usata in tantissimo software libero
ed &egrave; un modello per la maggior parte delle licenze per questo
tipo di programmi.
Si trova di solito in un file chiamato <tt/COPYING/,
con una versione per le librerie in un file chiamato <tt/COPYING.LIB/.
Anche qualche pubblicazione della FSF (free software foundation)
potrebbe esservi d'aiuto.

<item>In particolare, il software libero pi&ugrave; interessante &egrave;
disponibile con sorgenti che possono essere consultati e corretti.
Talvolta &egrave persino possibile prendere in prestito del codice.
Leggete con cura le licenze specifiche ed agite in conformit&agrave;
ad esse.

<item>C'&egrave; una FAQ per comp.lang.asm.x86 che risponde a domande generiche
circa la programmazione in assembly su x86 e a domande circa alcuni 
assemblatori commerciali in ambiente DOS a 16 bit.
Alcune riguardano la programmazione libera in asm a 32 bit, cos&igrave;
potreste essere interessati a leggere queste FAQ...

	<url url="http://www2.dgsys.com/&tilde;raymoon/faq/asmfaq.zip">

<item>Esistono FAQ e documentazione riguardanti la programmazione sulla
vostra piattaforma preferita, qualunque essa sia, che dovreste consultare
per questioni specifiche alla piattaforma stessa non direttamente correlate
alla programmazione in assembler.
</itemize>

<sect1>Storia
<p>
Ogni versione contiene alcune correzioni e rettifiche di poco conto
che non &egrave; necessario menzionare ogni volta.
<descrip>
<tag/Versione 0.1	23 apr 1996/
  Francois-Rene «Far&eacute;» Rideau &lt;rideau@ens.fr&gt;
  crea e pubblica il primo mini-HOWTO,
  perch&eacute; «Non ne posso pi&ugrave; di rispondere sempre
  alle stesse domande su comp.lang.asm.x86»
<tag/Versione 0.2	4 mag 1996/ *
<tag/Versione 0.3c	15 giu 1996/ *
<tag/Versione 0.3f	17 ott 1996/
  Trovata l'opzione -fasm per abilitare l'assemblatore inline di GCC senza
  le ottimizzazioni -O
<tag/Versione 0.3g	2 nov 1996/
  Creata la storia del documento. Aggiunti i riferimenti nella sezione
  sulla compilazione incrociata.
  Aggiunta la sezione circa la programmazione dell'I/O sotto Linux (video
  in particolare).
<tag/Versione 0.3h	6 nov 1996/
  maggiori informazioni sulla compilazione incrociata. Vedere devel/msdos su
  sunsite.
<tag/Versione 0.3i	16 nov 1996/
  NASM sta diventando molto affidabile. 
<tag/Versione 0.3j	24 nov 1996/
  Riferimento alla traduzione in francese.
<tag/Versione 0.3k	19 dic 1996/
  Cosa? Mi ero dimenticato di fare riferimento a Terse???
<tag/Versione 0.3l	11 gen 1997/ *
<tag/Versione 0.4pre1	13 gen 1997/
  Il mini-HOWTO in formato testo
  viene trasformato in un completo HOWTO linuxdoc-sgml,
  per vedere come sono gli SGML tools.
<tag/Versione 0.4	20 gen 1997/
  Primo rilascio dell'HOWTO come tale.
<tag/Versione 0.4a	20 gen 1997/
  Aggiunta la sezione «ringraziamenti».
<tag/Versione 0.4b	3 feb 1997/
  Spostato NASM: ora &egrave; prima di AS86
<tag/Versione 0.4c	9 feb 1997/
  Aggiunta la sezione «avete bisogno dell'assembly?»
<tag/Versione 0.4d	28 feb 1997/
  Annuncio prematuro di un nuovo responsabile dell'Assembly-HOWTO.
<tag/Versione 0.4e	13 mar 1997/
  Rilascio per DrLinux
<tag/Versione 0.4f	20 mar 1997/ *
<tag/Versione 0.4g	30 mar 1997/ *
<tag/Versione 0.4h	19 giu 1997/
  ancora aggiunte a «come NON usare l'assembly»;
 aggiornamenti su NASM, GAS.
<tag/Versione 0.4i	17 luglio 1997/
  informazioni sull'accesso al modo a 16 bit da Linux.
<tag/Versione 0.4j	7 settembre 1997/ *
<tag/Versione 0.4k	19 ottobre 1997/ *
<tag/Versione 0.4l	16 novembre 1997/
  rilascio per LSL, sesta edizione.

  Questo &egrave; ancora un altro
ultimo-rilascio-di-Far&eacute;-prima-che-un-altro-curatore-gli-subentri (?)

</descrip>


<sect1>Ringraziamenti
<p>
Vorrei ringraziare le seguenti persone, in ordine di apparizione:
<itemize>
<item><url url="mailto:sepolto.vivo@nella.posta" name="Linus Torvalds">
	per Linux
<item><url url="mailto:bde@zeta.org.au" name="Bruce Evans">
	per bcc da cui &egrave; estratto as86
<item><url url="mailto:anakin@poboxes.com" name="Simon Tatham"> e
      <url url="mailto:jules@earthcorp.com" name="Julian Hall">
	per NASM
<item><url url="mailto:jim-neil@digital.net" name="Jim Neil">
	per Terse
<item><url url="mailto:linux-howto@sunsite.unc.edu" name="Tim Bynum">
	perch&eacute; mantiene gli HOWTO
<item><url url="mailto:raymoon@moonware.dgsys.com" name="Raymond Moon">
	per le sue FAQ
<item><url url="mailto:dumas@excalibur.ibp.fr" name="Eric Dumas">
        per la sua traduzione in francese del mini-HOWTO
        (&egrave; una cosa triste per l'autore originale essere francese e
        scrivere in inglese)
<item><url url="mailto:paul@geeky1.ebtech.net" name="Paul Anderson">
	e <url url="mailto:rahim@megsinet.net" name="Rahim Azizarab">
	per l'aiuto, se non per aver rilevato l'HOWTO.
<item>Tutte le persone che hanno dato il loro contributo con idee, commenti
        e supporto morale.
</itemize>



<sect>AVETE BISOGNO DELL'ASSEMBLY?<label id="doyouneedasm">
<p>
Beh, non vorrei interferire con ci&ograve; che state facendo, ma
ecco alcuni consigli derivanti da una esperienza
ottenuta faticosamente.


<sect1>Pro e contro
<p>

<sect2>I vantaggi dell'assembly
<p>
L'assembly pu&ograve; esprimere cose molto a basso livello:
<itemize>
<item>potete accedere a registri e ad I/O dipendenti dalla macchina.
<item>potete controllare l'esatto comportamento di codice
        in sezioni critiche che potrebbe comportare il bloccarsi di
        hardware o I/O.
<item>potete trasgredire le convenzioni del vostro compilatore abituale,
        il che potrebbe permettere alcune ottimizzazioni
        (come ad esempio violare temporaneamente le regole per il garbage
        collecting, threading, ecc).
<item>ottenere accesso a modi di programmazione insoliti del vostro
        processore (ad esempio codice a 16 bit per l'avvio o l'interfaccia
        BIOS sui PC Intel).
<item>potete costruire interfacce tra frammenti di codice che usano
        convenzioni incompatibili
        (ad esempio prodotti da compilatori diversi
         o separati da una interfaccia a basso livello).
<item>potete produrre codice ragionevolmente veloce per cicli stretti 
        per far fronte ad un compilatore non-ottimizzante di qualit&agrave;
        scadente (ma dopotutto sono disponibili compilatori ottimizzanti
        liberi!).
<item>potete produrre codice ottimizzato a mano che risulta ottimo per
        la vostra particolare configurazione hardware, ma non
        per quella di chiunque altro.
<item>potete scrivere del codice per il compilatore ottimizzante del
        vostro nuovo linguaggio
        (&egrave; qualcosa che poche persone fanno, ed anche loro
        non lo fanno molto spesso).
</itemize>
<p>


<sect2>Gli svantaggi dell'assembly
<p>
L'assembly &egrave; un linguaggio molto a basso livello
(pi&ugrave; in basso c'&egrave; solo la codifica a mano
delle istruzioni in codice binario).

Ci&ograve; significa:
<itemize>
<item>All'inizio &egrave; lungo e tedioso da scrivere.
<item>&Egrave; notevolmente soggetto ad errori.
<item>Gli errori saranno molto difficili da scovare.
<item>&Egrave; molto difficile da comprendere e modificare,
        in altre parole da mantenere.
<item>Il risultato &egrave; decisamente non portabile verso altre architetture,
        esistenti o future.
<item>Il vostro codice verr&agrave; ottimizzato solo per una certa
        implementazione di una stessa architettura:
        ad esempio, tra le piattaforme compatibili Intel,
        avere CPU diverse o differenti configurazioni (ampiezza del bus,
        velocit&agrave; e dimensioni relative di CPU/cache/RAM/bus/dischi,
        presenza di FPU, estensioni MMX, ecc.) pu&ograve; richiedere tecniche 
        di ottimizzazione radicalmente diverse.
	I tipi di CPU comprendono gi&agrave;
	Intel 386, 486, Pentium, PPro, Pentium II;
	Cyrix 5x86, 6x86; AMD K5, K6.
        Inoltre, continuano ad apparire nuovi tipi, perci&ograve;
        non aspettatevi che questo elenco o il vostro codice siano aggiornati.
<item>Il vostro codice potrebbe inoltre non essere portabile verso piattaforme
        con sistemi operativi differenti ma con la stessa architettura per
        la mancanza di strumenti adeguati
        (beh, GAS pare funzionare su tutte le piattaforme; a quanto sembra,
        NASM funziona o pu&ograve; essere reso funzionante su tutte le
        piattaforme Intel).
<item>Perdete pi&ugrave; tempo su pochi dettagli e non potete concentrarvi
        sulla progettazione algoritmica su piccola e grande scala che,
        come &egrave; noto, porta il maggior contributo
        alla velocit&agrave; del programma.
        Per esempio, potresete perdere del tempo per scrivere in assembly
        delle primitive molto veloci per la manipolazione di liste o matrici,
        quando sarebbe bastato utilizzare una tabella hash per accelerare molto
        di pi&ugrave; il vostro programma. Magari, in un altro contesto,
        sarebbe servito un albero binario, o qualche struttura ad alto
        livello distribuita su un cluster di CPU.
<item>Un piccolo cambiamento nell'impostazione algoritmica potrebbe
        far perdere ogni validit&agrave; a tutto il codice assembly
        gi&agrave; esistente.
        Perci&ograve; o siete pronti a (ed in grado di) riscriverlo tutto,
        oppure siete vincolati ad una particolare impostazione algoritmica.
<item>Per quanto riguarda il codice che non si scosta troppo da quello
        che &egrave; presente nei benchmark convenzionali,
        i compilatori ottimizzanti commerciali permettono di ottenere
        prestazioni migliori rispetto all'«assembly manuale»
        (beh, ci&ograve; &egrave; meno vero sulle architetture x86
        rispetto alle architetture RISC e forse meno vero per compilatori
        largamente disponibili/liberi; comunque, per codice C tipico, GCC se
        la cava discretamente).
<item>E in ogni caso, come dice il moderatore John Levine su comp.compilers,
        «i compilatori rendono decisamente pi&ugrave; facile utilizzare
        strutture dati complesse, non si stancano a met&agrave; strada
        e ci si pu&ograve; aspettare che generino codice abbastanza buono».
        Inoltre provvederanno a propagare <em/correttamente/ trasformazioni
        di codice attraverso tutto il (lunghissimo) programma quando
        si tratter&agrave; di ottimizzare codice tra i confini delle procedure
        e dei moduli.
</itemize>
<p>

<sect2>Valutazioni
<p>
Tutto sommato, potreste notare che
nonostante l'uso dell'assembly sia talvolta
necessario (o semplicemente utile, in alcuni casi), 
sar&agrave; il caso che:
<itemize>
<item>minimizziate l'uso del codice assembly;
<item>incapsuliate questo codice in interfacce ben definite;
<item>facciate generare automaticamente il vostro codice assembly
        da strutture espresse in un linguaggio a pi&ugrave; alto livello
        rispetto all'assembly stesso (ad esempio le macro dell'assembly
        inline di GCC);
<item>facciate tradurre in assembly questi programmi da strumenti automatici;
<item>facciate ottimizzare questo codice, se possibile;
<item>tutti i punti di cui sopra,
        cio&egrave; scriviate (un'estensione ad) un backend
        per un compilatore ottimizzante.
</itemize>

Anche nei casi in cui l'assembly &egrave; necessario (ad esempio, nello
sviluppo di sistemi operativi),
scoprirete che non ne serve poi molto
e che i principi precedenti continuano a valere.

A questo riguardo, date un'occhiata ai sorgenti del kernel di Linux:
poco assembly, giusto lo stretto necessario,
il che ha come risultato un sistema operativo veloce, affidabile, portabile
e mantenibile.
Anche un gioco di successo come DOOM &egrave; stato scritto quasi completamente
in C, con solo una minuscola parte scritta in assembly per renderlo
pi&ugrave; veloce. 


<sect1>Come NON usare l'assembly
<p>

<sect2>Procedura generale per ottenere codice efficiente
<p>
Come dice Charles Fiterman su comp.compilers
circa il confronto tra codice assembly generato
a mano o automaticamente,

«L'uomo dovrebbe sempre vincere, ed eccone i motivi:
<itemize>
<item>Primo passo: l'uomo scrive il tutto in un linguaggio ad alto livello.
<item>Secondo passo: provvede ad un profiling per trovare i punti in cui
      si perde pi&ugrave; tempo.
<item>Terzo passo: fa produrre al compilatore codice assembly per quelle
      piccole sezioni di codice.
<item>Quarto passo: le perfeziona a mano cercando piccoli miglioramenti
      rispetto al codice generato dalla macchina.
</itemize>

L'uomo vince perch&eacute; sa usare la macchina.»


<sect2>Linguaggi con compilatori ottimizzanti
<p>
I linguaggi quali
ObjectiveCAML, SML, CommonLISP, Scheme, ADA, Pascal, C, C++,
tra gli altri,
dispongono di compilatori ottimizzanti liberi
che ottimizzeranno il grosso dei vostri programmi
(e spesso otterranno risultati migliori rispetto all'assembly manuale
anche per cicli stretti),
permettendovi nel frattempo di concentrarvi su dettagli pi&ugrave;
ad alto livello, il tutto senza vietarvi di ottenere qualche punto
percentuale di prestazioni in pi&ugrave; nella maniera espressa
sopra, una volta che il vostro progetto
avr&agrave; raggiunto un'impostazione stabile.

Certo, ci sono anche compilatori ottimizzanti commerciali per la maggior
parte di quei linguaggi!

Alcuni linguaggi hanno compilatori che producono codice C, che pu&ograve;
essere ulteriormente ottimizzato da un compilatore C.
LISP, Scheme, Perl e molti altri
fanno parte di questa categoria.
La velocit&agrave &egrave; abbastanza buona.



<sect2>Procedura generale per accelerare il vostro codice
<p>
Per quanto riguarda l'accelerazione del vostro codice,
dovreste restringerla alle parti di un programma che uno
strumento di profiling ha decisamente identificato
come un collo di bottiglia.

Perci&ograve;, se identificate qualche porzione di codice come troppo
lenta, dovreste:
<itemize>
<item>prima di tutto provare ad usare un algoritmo migliore;
<item>poi provare a compilarla invece di interpretarla;
<item>poi provare ad abilitare e raffinare l'ottimizzazione per il vostro
compilatore;
<item>poi dare al compilatore dei consigli su come ottimizzare
(informazione sui tipi in LISP; uso di register con GCC;
un mucchio di opzioni nella maggior parte dei compilatori, ecc.);
<item>infine, se &egrave; il caso, ripiegate sulla programmazione assembly.
</itemize>

Come ultima cosa, prima che vi riduciate a scrivere assembly,
dovreste ispezionare il codice generato,
per controllare che il problema risieda proprio nella cattiva generazione
del codice, visto che potrebbe anche non essere cos&igrave:
il codice generato dal compilatore potrebbe essere migliore di quanto
avreste potuto fare voi, 
specialmente sulle moderne architetture multi-pipelined!
Le parti lente di un programma potrebbero essere intrinsecamente tali.
I pi&ugrave; grossi problemi sulle architetture moderne con processori veloci
sono dovuti a ritardi di accesso alla memoria, cache-miss, TLB miss,
e page fault;
l'ottimizzazione sui registri diventa inutile, ed otterrete risultati
migliori riprogettando le strutture dati ed il threading per ottenere
una miglior localit&agrave; nell'accesso alla memoria.
Potrebbe forse essere d'aiuto un approccio completamente diverso al problema.

<sect2>Ispezione del codice generato dal compilatore
<p>
Ci sono molte ragioni per ispezionare il codice assembly generato dal
compilatore.
Ecco cosa potete fare con tale codice:
<itemize>
<item>controllate se il codice generato
        pu&ograve; essere migliorato in maniera ovvia con assembly manuale
        (o con le opportune opzioni per il compilatore).
<item>Quando &egrave; il caso, partite da codice generato e modificatelo,
        invece di ripartire da zero.
<item>Pi&ugrave; in generale, utilizzate il codice generato come
        stub da modificare. In questo modo, almeno, viene
        gestito correttamente il modo in cui le vostre routine
        assembly si interfacciano col mondo esterno.
<item>Rintracciare dei bug nel vostro compilatore (raramente, si spera).

</itemize>

Il modo canonico per far generare codice assembly
&egrave; invocare con il flag <tt/-S/ il vostro compilatore.
Ci&ograve; funziona con la maggior parte dei compilatori UNIX,
compreso il compilatore C di GNU (GCC), ma nel vostro caso le cose potrebbero
andare diversamente.
Nel caso di GCC, con l'opzione <tt/-fverbose-asm/ verr&agrave; prodotto
codice assembly pi&ugrave; comprensibile.
Certo, se volete ottenere buon codice assembly, non dimenticate di dare
i soliti consigli e le solite opzioni per l'ottimizzazione! 


<sect>ASSEMBLATORI
<p>

<sect1>Assembly inline di GCC
<p>
Il noto compilatore GNU C/C++ (GCC),
un compilatore ottimizzante a 32-bit alla base del progetto GNU,
supporta l'architettura x86 abbastanza bene,
e fornisce la possibilit&agrave; di inserire codice assembly nei programmi C,
in modo tale che l'allocazione dei registri pu&ograve; essere o specificata
o lasciata a GCC.
GCC funziona sulla maggior parte delle piattaforme disponibili,
tra le quali sono degne di nota Linux, *BSD, VSTa, OS/2, *DOS, Win*, ecc.

<sect2>Dove trovare GCC
<p>
Il sito originale di GCC &egrave; il sito FTP di GNU
	<url url="ftp://prep.ai.mit.edu/pub/gnu/">
in cui si trova anche tutto il software applicativo del progetto GNU
che &egrave; stato rilasciato.

Versioni configurate e precompilate per Linux possono essere trovate in
	<url url="ftp://sunsite.unc.edu/pub/Linux/GCC/">.
Esistono un sacco di mirror FTP di entrambi i siti
in tutte le parti del mondo, cos&igrave; come copie su CD-ROM.

Recentemente, lo sviluppo di GCC si &egrave; biforcato.
Maggiori notizie sulla versione sperimentale, egcs, presso
	<url url="http://www.cygnus.com/egcs/">.

Dovreste trovare dei sorgenti adattati per il vostro sistema operativo
preferito e dei binari precompilati ai soliti siti FTP.

La versione pi&ugrave; comune per DOS si chiama DJGPP e pu&ograve;
essere trovata nelle directory con questo nome nei siti FTP.
Vedere:

	<url url="http://www.delorie.com/djgpp/">


C'&egrave; anche una versione di GCC per OS/2 chiamata EMX,
che funziona anche sotto DOS ed include molte routine di libreria per
l'emulazione di UNIX.
Date un'occhiata dalle parti di:

	<url url="http://www.leo.org/pub/comp/os/os2/gnu/emx+gcc/">

	<url url="http://warp.eecs.berkeley.edu/os2/software/shareware/emx.html">

	<url url="ftp://ftp-os2.cdrom.com/pub/os2/emx09c/">


<sect2>Dove trovare documentazione per l'assemblatore inline di GCC
<p>
La documentazione di GCC include file di documentazione in formato texinfo.
Potete compilarli con TeX e poi stampare il risultato,
oppure convertirli in .info e sfogliarli con emacs,
oppure ancora convertirli in .html o (con gli strumenti appropriati)
in tutto ci&ograve; che volete, oppure semplicemente leggerli cos&igrave;
come sono.

Di solito i file .info si trovano in ogni buona installazione di GCC.

La sezione corretta da cercare &egrave;:
	<tt/C Extensions::Extended Asm::/

La sezione
	<tt/Invoking GCC::Submodel Options::i386 Options::/
potrebbe anch'essa rivelarsi utile.
In particolare, d&agrave; i vincoli sui nomi dei registri
specifici per l'i386:
abcdSDB corrispondono rispettivamente a:
<tt/&percnt;eax/, <tt/&percnt;ebx/, <tt/&percnt;ecx/, <tt/&percnt;edx/,
<tt/&percnt;esi/, <tt/&percnt;edi/, <tt/&percnt;ebp/
(nessuna lettera per <tt/&percnt;esp/).

La DJGPP Games resource (non solo per hacker dei giochi) ha questa
pagina apposta per l'assembly:

	<url url="http://www.rt66.com/&tilde;brennan/djgpp/djgpp&lowbar;asm.html">

Infine, c'&egrave; una pagina web chiamata «DJGPP Quick ASM Programming Guide»
che tratta URL, FAQ, sintassi asm AT&amp;T per x86, alcune informazioni
sull'asm inline e la conversione dei file .obj/.lib:

	<url url="http://remus.rutgers.edu/&tilde;avly/djasm.html">

GCC dipende da GAS per l'assembling e segue la sua
sintassi (vedere in seguito); 
se usate l'asm inline, badate bene: &egrave; necessario che i caratteri
«percento» siano protetti dall'espansione per poter essere passati a GAS.
Vedere la sezione su GAS in seguito.

Potete trovare <em/un sacco/ di esempi utili nella
sottodirectory <tt>linux/include/asm-i386/</tt> dei sorgenti
del kernel di Linux.


<sect2>Invocare GCC per fargli trattare correttamente l'assembly inline
<p>
Assicuratevi di invocare GCC con il
flag <tt/-O/ ( oppure <tt/-O2/, <tt/-O3/, ecc.) per
abilitare le ottimizzazioni e l'assembly inline.
Se non lo fate, il vostro codice potrebbe venire compilato ma non essere
eseguito correttamente!!!
In realt&agrave; (lodi smisurate a Tim Potter, timbo@mohpit.air.net.au)
&egrave; sufficiente utilizzare il flag <tt/-fasm/ (e
forse <tt/-finline-functions/)
che attiva solo una parte di tutte le funzionalit&agrave; abilitate
da <tt/-O/.
Cos&igrave;, se avete problemi a causa di bug nelle ottimizzazioni
della vostra particolare versione/implementazione 
di GCC, potete comunque usare l'asm inline.
In maniera analoga, usate -fno-asm per disabilitare l'assembly inline
(perch&eacute; dovreste?).

Pi&ugrave; in generale, buoni flag di compilazione per GCC sulla piattaforma
x86 sono
<code>
	gcc -O2 -fomit-frame-pointer -m386 -Wall
</code>

<tt/-O2/ &egrave; il giusto livello di ottimizzazione. Ottimizzare
oltre produce codice che &egrave; parecchio pi&ugrave; grande, ma
solo di poco pi&ugrave; veloce;
tale sovraottimizzazione potrebbe essere utile solo per cicli stretti (se
ce ne sono), che potreste comunque realizzare in assembly;
se ne sentite la necessit&agrave;, fatelo solo per le poche routine che ne
hanno bisogno.

<tt/-fomit-frame-pointer/ consente al codice generato di evitare la stupida
gestione del frame pointer, il che rende il codice pi&ugrave; piccolo e veloce
e libera un registro per ulteriori ottimizzazioni.
Ciò preclude il comodo utilizzo degli strumenti per il debugging (<tt/gdb/),
ma nel momento in cui usate questi strumenti, non &egrave; che vi importi
poi molto delle dimensioni e della velocit&agrave;.

<tt/-m386/ produce codice pi&ugrave; compatto, senza alcun rallentamento
misurabile (notate che codice piccolo significa anche meno I/O per il disco
ed esecuzione pi&ugrave; rapida), ma forse sui suddetti cicli stretti
potreste apprezzare <tt/-mpentium/ per il GCC speciale che ottimizza
per pentium (sempre che abbiate come obiettivo
proprio una piattaforma pentium).

<tt/-Wall/ abilita tutti gli avvisi e vi aiuta a scovare errori stupidi
ed ovvii.

Per ottimizzare ancora di pi&ugrave;, l'opzione <tt/-mregparm=2/ e/o il
corrispondente attributo per le funzioni vi potrebbero essere utili<,
ma potrebbero porre un sacco di problemi qualora doveste fare un link con
codice estraneo...

Notate che potete rendere questi flag quelli predefiniti modificando il
file
	<tt>/usr/lib/gcc-lib/i486-linux/2.7.2.2/specs</tt>
o dovunque esso si trovi nel vostro sistema (meglio non aggiungere
-Wall in quella sede, comunque).


<sect1>GAS
<p>
GAS &egrave; l'assemblatore GNU, su cui fa affidamento GCC.


<sect2>Dove trovarlo
<p>
Lo trovate nello stesso posto dove avete trovato GCC,
in un pacchetto denominato binutils.


<sect2>Cos'&egrave; la sintassi AT&amp;T
<p>
Poich&eacute; GAS &egrave; stato concepito per supportare un compilatore
UNIX a 32 bit, esso utilizza la notazione standard «AT&amp;T», che
assomiglia molto alla sintassi degli assemblatori standard per m68k
ed &egrave; standard nel mondo UNIX.
Questa sintassi non &egrave; n&eacute; peggiore n&eacute; migliore della
sintassi «Intel».
&Egrave semplicemente diversa.
Una volta che ci si &egrave abituati,
la si trova molto pi&ugrave regolare della sintassi Intel,
anche se un po' noiosa.

Ecco le cose a cui prestare maggiore attenzione quando si ha a
che fare con la sintassi di GAS:
<itemize>
<item>
I nomi dei registri hanno <tt/&percnt;/ come prefisso, cosicch&eacute;
i registri sono <tt/&percnt;eax/, <tt/&percnt;dl/ e cos&igrave via
invece di solo <tt/eax/, <tt/dl/, ecc.
Ci&ograve; fa s&igrave; che sia possibile includere simboli C esterni
direttamente nel sorgente assembly, senza alcun rischio di confusione
e senza alcun bisogno di orribili underscore anteposti.
<item>
L'ordine degli operandi &egrave; la sorgente (o sorgenti) per prima e
la destinazione per ultima, che &egrave; l'opposto della convenzione
Intel di avere prima la destinazione e le sorgenti per ultime.
Quindi, ci&ograve; che nella sintassi intel
&egrave; <tt/mov ax,dx/ (carica il contenuto del registro <tt/dx/ nel
registro <tt/ax/) diventer&agrave;
<tt/mov &percnt;dx, &percnt;ax/
nella sintassi AT&amp;T.

<item>
La lunghezza dell'operando &egrave specificata tramite un suffisso al nome
dell'istruzione.
Il suffisso &egrave; <tt/b/ per byte (8 bit), <tt/w/ per word (16 bit)
e <tt/l/ per long (32 bit). Ad esempio, la sintassi corretta per
l'istruzione menzionata poco fa sarebbe stata <tt/movw &percnt;dx,&percnt;ax/.
Comunque, gas non richiede una sintassi AT&amp;T rigorosa,
quindi il suffisso &egrave; opzionale quando la lunghezza pu&ograve; essere
ricavata dai registri usati come operandi, altrimenti viene posta a 32 bit per
default (con un avviso).
<item>
Gli operandi immediati sono indicati con il prefisso <tt/&dollar;/,
come in <tt/addl &dollar;5,&percnt;eax/
(somma il valore long 5 al registro <tt/&percnt;eax/).
<item>
L'assenza di prefisso in un operando indica che &egrave; un indirizzo di
memoria;
perci&ograve; <tt/movl &dollar;pippo,&percnt;eax/ mette l'<em/indirizzo/
della variabile <tt/pippo/ nel registro <tt/&percnt;eax/,
mentre <tt/movl pippo,&percnt;eax/ mette il <tt/contenuto/ della variabile
<tt/pippo/ nel registro <tt/&percnt;eax/.
<item>
L'indicizzazione o l'indirezione &egrave; ottenuta racchiudendo il registro
indice o l'indirizzo della cella di memoria di indirezione tra parentesi,
come in
<tt/testb &dollar;0x80,17(&percnt;ebp)/
(esegue un test sul bit pi&ugrave alto del valore byte all'offset 17 dalla
cella puntata da  <tt/&percnt;ebp/).
</itemize>


Esiste un programma per aiutarvi a convertire programmi
dalla sintassi TASM alla sintassi AT&amp;T. Date un'occhiata a

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

GAS ha una documentazione esauriente in formato TeXinfo,
che trovate nella distribuzione dei sorgenti (e forse altrove).
Potete sfogliare le pagine .info estratte con emacs o con ci&ograve che
pi&ugrave vi aggrada.
C'era un file chiamato gas.doc o as.doc dalle parti del pacchetto sorgente
di GAS, ma &egrave; stato incorporato nella documentazione in TeXinfo.
Certo, in caso di dubbio, la documentazione definitiva
sono i sorgenti stessi!
Una sezione che vi interesser&agrave; particolarmente &egrave;
	<tt/Machine Dependencies::i386-Dependent::/


Ancora, i sorgenti di Linux (il kernel del sistema operativo) si rivelano
buoni esempi;
date un'occhiata ai seguenti file sotto linux/arch/i386:

<tt>kernel/*.S, boot/compressed/*.S, mathemu/*.S</tt>

Se state scrivendo qualcosa tipo un linguaggio, un pacchetto per i thread, ecc.
potreste anche guardare come si comportano altri
linguaggi (OCaml, gforth, ecc.) o pacchetti per i thread
(QuickThreads, MIT pthreads, LinuxThreads, etc), o quel che &egrave;.

Infine, limitarsi a compilare un programma C in assembly
potrebbe mostrarvi la sintassi del genere di istruzioni che vi interessano.
Vedere la precedente sezione
<ref id="doyouneedasm" name="Avete bisogno dell'assembly?">.



<sect2>Modo a 16 bit limitato
<p>
GAS &egrave; un assemblatore a 32 bit, il suo compito &egrave; quello
di supportare un compilatore a 32 bit.
Attualmente ha solo un supporto limitato per il modo a 16 bit, che consiste
nell'anteporre i prefissi per i 32 bit alle istruzioni,
cosicch&eacute; scrivete codice a 32 bit che gira nel modo a 16 bit su una
CPU a 32 bit.
In entrambi i modi supporta l'uso dei registri a 16 bit,
ma non l'indirizzamento a 16 bit.

   Utilizzate le direttive <tt/.code16/ e <tt/.code32/ per passare da un
modo all'altro.
Notate che un'istruzione di assembly inline
	<tt/asm(&dquot;.code16&bsol;n&dquot;)/
consentir&agrave; a GCC di produrre codice a 32 bit che girer&agrave; in
real mode!

   Mi &egrave; stato detto che la maggior parte del codice necessario
per supportare pienamente la programmazione nel modo a 16 bit &egrave;
stata aggiunta a GAS da Bryan Ford (si prega di confermare),
tuttavia non si trova in nessuna delle distribuzioni che ho provato,
fino a binutils-2.8.1.x ... sarebbero gradite maggiori informazioni su
questo argomento.

   Una soluzione economica &egrave; quella di definire macro (vedere in
seguito) che in qualche modo producono la codifica binaria (con <tt/.byte/)
solo per le istruzioni del modo a 16 bit di cui avete bisogno (quasi nessuna
se usate il codice a 16 bit come sopra e se potete supporre con certezza
che il codice girer&agrave; su una CPU x86 in grado di gestire i 32 bit).
Per trovare la codifica corretta, potete ispirarvi ai sorgenti degli
assemblatori in grado di gestire i 16 bit.

<sect1>GASP
<p>
GASP (GAS Preprocessor) &egrave; il Preprocessore per GAS.
Aggiunge macro e dei costrutti sintattici carini a GAS.


<sect2>Dove trovare GASP
<p>
GASP si trova assieme a GAS nell'archivio binutils di GNU.


<sect2>Come funziona
<p>
Funziona come un filtro, in modo molto simile a cpp e programmi analoghi.
Non ho alcuna idea sui dettagli, ma assieme ad esso trovate
documentazione relativa in texinfo, perci&ograve; limitatevi a sfogliarla
(in .info), stamparla, sviscerarla.
GAS con GASP mi sembra un comune assemblatore con macro.

<sect1>NASM
<p>
Il progetto Netwide Assembler sta producendo un ulteriore assemblatore,
scritto in C, che dovrebbe essere abbastanza modulare per supportare
eventualmente tutte le sintassi ed i formati di oggetto conosciuti.

<sect2>Dove trovare NASM
<p>
	<url url="http://www.cryogen.com/Nasm">

Le release binarie, nel vostro solito mirror di sunsite, sotto
	<tt>devel/lang/asm/</tt>.
Dovrebbero inoltre essere disponibili come .rpm o .deb
nei contrib delle vostre distribuzioni RedHat/Debian.

<sect2>Cosa fa
<p>
Nel momento in cui questo HOWTO viene scritto, la versione corrente di
NASM &egrave; 0.96.

La sintassi &egrave; in stile Intel.
&Egrave integrato del supporto per le macro.
I formati di file oggetto supportati sono
<tt/bin/, <tt/aout/, <tt/coff/, <tt/elf/, <tt/as86/,
(DOS) <tt/obj/, <tt/win32/, <tt/rdf/ (il loro formato specifico).

NASM pu&ograve; essere usato come backend per il compilatore libero LCC
(sono inclusi i file di supporto).

Di certo NASM si evolve troppo rapidamente perch&eacute; questo HOWTO 
possa essere aggiornato.
A meno che voi stiate usando BCC come compilatore a 16 bit
(il che esula dagli scopi di questo HOWTO sulla programmazione a 32 bit),
dovreste usare NASM invece di, ad esempio, ASM o MASM,
perch&eacute &egrave; attivamente supportato online
e gira su tutte le piattaforme.

Nota: con NASM trovate anche un disassemblatore, NDISASM.

Il suo parser scritto a mano lo rende molto pi&ugrave; veloce di GAS
anche se, ovviamente, non supporta tre fantastiliardi di architetture
differenti.
Se volete generare codice per x86, dovrebbe essere l'assemblatore
da scegliere.

<sect1>AS86
<p>
AS86 &egrave; un assemblatore 80x86 a 16 e 32 bit,
parte del compilatore C di Bruce Evans (BCC).
Segue fondamentalmente la sintassi Intel,
anche se ne discosta leggermente per quanto
riguarda le modalit&agrave; di indirizzamento.

<sect2>Dove procurarsi AS86
<p>
Una versione decisamente superata di AS86 &egrave; distribuita
da HJLu semplicemente per compilare il kernel di Linux, in un pacchetto
chiamato bin86 (versione corrente: 0.4),
disponibile in ogni archivio di GCC per Linux.
Tuttavia non consiglio a nessuno di usarlo per qualcosa che non sia
compilare Linux. Questa versione supporta solo una versione modificata
del formato per file oggetto di minix, che non &egrave; supportata dalle
binutils GNU o altro e che ha qualche bug nel modo a 32 bit,
quindi fareste proprio meglio a tenerla solo per compilare Linux.

Le versioni pi&ugrave; recenti realizzate da Bruce Evans (bde@zeta.org.au)
sono pubblicate assieme alla distribuzione FreeBSD.
Beh, lo erano: non sono riuscito a trovare i sorgenti dalla distribuzione
2.1 in poi :(
Quindi, metto i sorgenti da me:

<url url="http:///www.eleves.ens.fr:8080/home/rideau/files/bcc-95.3.12.src.tgz">

Il progetto Linux/8086 (conosciuto anche come ELKS) sta in qualche modo
mantenendo bcc (anche se non credo che abbiano incluso le patch per i
32 bit).
Date un'occhiata dalle parti di
<url url="http://www.linux.org.uk/Linux8086.html">
<url url="ftp://linux.mit.edu/">.

Tra l'altro, queste versione pi&ugrave; recenti, contrariamente
a quelle di HJLu, supportano il formato GNU a.out per Linux,
cosicch&eacute; &egrave; possibile il linking tra il vostro codice ed
i programmi Linux e/o l'utilizzo dei soliti strumenti dal pacchetto
GNU binutil per manipolare i vostri dati.
Questa versione pu&ograve; coesistere senza alcun danno con quella precedente
(vedere la domanda relativa in seguito).

BCC, versione del 12 marzo 1995 e precedenti,
esegue i push ed i pop di segmenti soltanto a 16 bit,
il che &egrave; non poco seccante quando si programma nel modo a 32 bit.

Una patch &egrave; disponibile nel progetto Tunes
	<url url="http://www.eleves.ens.fr:8080/home/rideau/Tunes/">
alla sottopagina
	<tt>files/tgz/tunes.0.0.0.25.src.tgz</tt>
nella directory decompressa
	<tt>LLL/i386/</tt>
La patch dovrebbe anche essere disponibile direttamente da
	<url url="http://www.eleves.ens.fr:8080/home/rideau/files/as86.bcc.patch.gz">
Bruce Evans ha accettato questa patch, cos&igrave; se un giorno ci sar&agrave;
da qualche parte una versione pi&ugrave; recente di bcc,
la patch dovrebbe essere stata inclusa.

<sect2>Come invocare l'assemblatore?
<p>
Ecco la voce nel Makefile di GNU per usare bcc allo scopo di
trasformare asm <tt/.s/ in oggetto <tt/.o/ ed ottenere un listato <tt/.l/ :

<code>
&percnt;.o &percnt;.l:        &percnt;.s
        bcc -3 -G -c -A-d -A-l -A&dollar;*.l -o &dollar;*.o &dollar;<
</code>

Togliete <tt/&percnt;.l/, <tt/-A-l/ e <tt/-A&dollar;*.l/
se non volete alcun listato.
Se volete qualcos'altro invece di un a.out GNU,
potete consultare la documentazione di bcc circa gli altri formati supportati
e/o utilizzare objcopy dal pacchetto delle GNU binutils.

<sect2>Dove trovare documentazione
<p>
La documentazione &egrave; quella che &egrave; inclusa nel pacchetto bcc.
Da qualche parte nel sito di FreeBSD sono inoltre disponibili
le pagine di manuale.
In caso di dubbi, i sorgenti stessi sono spesso una buona documentazione:
non &egrave; molto ben commentata, ma lo stile di programmazione &egrave;
chiaro.
Potreste provare a vedere come as86 &egrave; utilizzato in Tunes 0.0.0.25...


<sect2>E se non riesco pi&ugrave; a compilare Linux con questa nuova versione?
<p>
Linus &egrave; sepolto vivo nella posta e la mia patch per compilare Linux
con as86 a.out per Linux non ce l'ha fatta ad arrivargli (!).
Ora, questo non dovrebbe avere importanza: limitatevi a tenere il vostro
as86 dal pacchetto bin86 in /usr/bin e lasciate che bcc installi l'as86
buono come /usr/local/libexec/i386/bcc/as dove dovrebbe risiedere.
Non avrete mai bisogno di chiamare esplicitamente questo as86 «buono»,
perch&eacute; bcc fa tutto come si deve, compresa la conversione dal formato
a.out di Linux quando viene invocato con le opzioni corrette;
limitatevi perci&ograve; ad assemblare usando bcc come
frontend, non fatelo direttamente con as86.


<sect1>ALTRI ASSEMBLATORI
<p>
Queste sono altre scelte possibili, non convenzionali, nel caso
in cui le precedenti non vi abbiano soddisfatto (perch&eacute;?).
Non le consiglio nei casi comuni (?),
ma potrebbero rivelarsi molto utili se l'assemblatore deve essere
integrato nel software che state progettando (ad esempio un sistema operativo
o un ambiente di sviluppo).



<sect2>L'assemblatore Win32Forth
<p>
Win32Forth &egrave; un sistema ANS FORTH a 32 bit <em/libero/
che gira sotto Win32s, Win95, Win NT.
Include un assemblatore libero a 32 bit (con sintassi prefissa o postfissa)
integrato nel linguaggio FORTH.
La gestione delle macro &egrave; realizzata con la piena potenza del
linguaggio FORTH;
<!--
  N.d.T.:
  era: reflective language FORTH; se qualcuno ha idea di come
  tradurre "reflective"...
-->
comunque, l'unico contesto di input e di output supportato &egrave; Win32Forth
stesso (nessuna creazione di file .obj ; certo, potreste aggiungerla
voi stessi).
Lo trovate qui:
	<url url="ftp://ftp.forth.org/pub/Forth/win32for/">


<sect2>Terse
<p>
Terse &egrave; uno strumento di programmazione con
<em>LA</em> sintassi dell'assemblatore pi&ugrave; compatta
per la famiglia x86!

Vedere <url url="http://www.terse.com">.
Si dice che ce ne sia un clone libero da qualche parte.
Sarebbe stato abbandonato in seguito a pretese infondate
secondo le quali la sintassi apparterrebbe all'autore originale.
Vi invito a continuarne lo sviluppo, nel caso la sintassi vi interessi.


<sect2>Assemblatori non liberi e/o non a 32 bit.
<p>
Potete trovare pi&ugrave; informazioni a riguardo, assieme alle basi
della programmazione assembly per x86, nelle FAQ di Raymond Moon
per comp.lang.asm.x86
<url url="http://www2.dgsys.com/&tilde;raymoon/faq/asmfaq.zip">

Va notato che tutti gli assemblatori che si basano sul DOS dovrebbero
funzionare sotto l'emulatore di DOS per Linux ed altri emulatori
analoghi cosicch&eacute;, se ne possedete gi&agrave; uno, potete continuare
ad usarlo in un vero sistema operativo.
Alcuni assemblatori recenti per DOS supportano anche COFF e/o altri formati
di file oggetto che sono supportati dalla libreria GNU BFD, cos&igrave;
potete usarli insieme ai vostri strumenti liberi a 32 bit, magari usando
GNU objcopy (che fa parte delle binutils) come filtro di conversione.



<sect>METAPROGRAMMAZIONE E MACRO
<p>
La programmazione in assembly &egrave; una scocciatura, tranne che per
sezioni critiche dei programmi.

Dovreste usare gli strumenti appropriati per il compito giusto,
quindi non scegliete l'assembly quando non &egrave; adatto;
C, OCAML, perl, Scheme potrebbero essere una scelta migliore
per la maggior parte della vostra programmazione.

Comunque, ci sono casi in cui questi strumenti non consentono un controllo
sufficientemente accurato della macchina e l'assembly risulta
utile o addirittura necessario.
In questi casi, vi sar&agrave; utile un sistema di macro e metaprogrammazione
che permetter&agrave; di ridurre ogni struttura ricorrente
in una definizione riutilizzabile molte volte, il che consente una
programmazione pi&ugrave; sicura, la propagazione automatica delle
modifiche alla struttura stessa, ecc.

Un assemblatore «liscio» &egrave; spesso insufficiente, anche quando
si sviluppano semplicemente piccole routine per un linking con il C.

<sect1>Cosa &egrave; integrato nei pacchetti menzionati
<p>
S&igrave;, lo so che questa sezione non contiene molte informazioni aggiornate.
Sentitevi liberi di contribuire ci&ograve; che scoprite sulla vostra pelle...

<sect2>GCC
<p>
GCC permette (e richiede) che voi specifichiate vincoli sui registri
nel vostro codice assembly inline cosicch&eacute; l'ottimizzatore
ne &egrave; sempre al corrente; perci&ograve; il codice assembly inline,
in realt&agrave;, non &egrave; per forza costituito da codice esatto,
ma da strutture.

Potete poi inserire il vostro assembly in macro di CPP ed in funzioni C
inline, cos&igrave; si pu&ograve; usare come una qualsiasi macro o funzione C.
Le funzioni inline assomigliano molto alle macro, ma il loro uso
risulta talvolta pi&ugrave; pulito.
Badate che in tutti questi casi si avr&agrave; una duplicazione di codice,
quindi in questo codice asm dovrebbero essere definite solo etichette
locali (del tipo <tt/1:/).
Comunque, una macro permetterebbe che il nome di una etichetta non definita
localmente venga passato come parametro (oppure utilizzate metodi aggiuntivi
di metaprogrammazione).
Inoltre, propagare codice asm inline diffonder&agrave; potenziali bug
presenti in esso, state quindi doppiamente attenti ai vincoli sui registri
in situazioni simili.

Infine, il linguaggio C stesso pu&ograve; essere considerato una buona
astrazione rispetto al linguaggio assembly, il che vi solleva
dalla maggior parte dei problemi legati all'assembling.

Fate attenzione: alcune ottimizzazioni riguardanti
il passaggio di argomenti a funzioni tramite registri possono rendere
dette funzioni inadatte ad essere chiamate da routine esterne (ed in
particolare da quelle scritte a mano in assembly) nel modo standard;
l'attributo «asmlinkage» potrebbe impedire ad una routine di preoccuparsi
di tale flag di ottimizzazione; guardatevi i sorgenti del kernel
per gli esempi.


<sect2>GAS
<p>
GAS fornisce del supporto per le macro, come &egrave; spiegato in
dettaglio nella documentazione texinfo.
GCC, oltra a riconoscere i file .s come assembly «grezzo» da inviare
a GAS, riconosce anche i file .S come file da passare attraverso CPP
prima di mandarli a GAS.
Ancora una volta, guardate i sorgenti di Linux per gli esempi.

<sect2>GASP
<p>
Aggiunge tutti i tipici trucchetti delle macro a GAS.
Consultate la sua documentazione texinfo.

<sect2>NASM
<p>
Anche NASM ha del supporto per le macro.
Date un'occhiata alla documentazione relativa.
Se avete qualche idea brillante,
potreste voler contattare gli autori,
dal momento che lo stanno sviluppando attivamente.
Nel frattempo, date un'occhiata ai filtri esterni presentati in seguito.

<sect2>AS86
<p>
Ha un po' di semplice supporto per le macro, ma non sono riuscito a
trovare della documentazione.
I sorgenti sono molto chiari perci&ograve; se siete interessati dovreste
capirli facilmente.
Se le capacit&agrave; di base non vi bastano, dovreste usare un filtro
esterno (vedere in seguito).


<sect2>ALTRI ASSEMBLATORI
<p>
<itemize>
<item>
Win32FORTH:
CODE ed END-CODE sono delle macro che non
commutano dal modo interpretazione al modo compilazione, cosicch&eacute;
avete pieno accesso alla potenza del FORTH durante l'assembling.
<item>
TUNES:
non funziona ancora, ma Scheme &egrave; un vero linguaggio
ad alto livello che consente metaprogrammazione arbitraria.
</itemize>


<sect1>Filtri esterni
<p>
Qualunque sia il supporto per le macro del vostro assemblatore,
o qualunque linguaggio utilizziate (perfino il C!),
se secondo voi il linguaggio non &egrave; sufficientemente espressivo,
potete far passare i file attraverso un filtro esterno con
una regola come questa nel Makefile:

<code>
&percnt;.s:    &percnt;.S altre&lowbar;dipendenze
	    &dollar;(FILTRO) &dollar;(OPZIONI&lowbar;DEL&lowbar;FILTRO) < &dollar;< > &dollar;@
</code>


<sect2>CPP
<p>
CPP non &egrave; molto espressivo, ma &egrave; sufficiente per
le cose facili, &egrave; standard ed &egrave; chiamato in modo trasparente
da GCC.

Per fare un esempio delle sue limitazioni, non si possono dichiarare
oggetti in modo tale che i distruttori vengano chiamati automaticamente
al termine del blocco di dichiarazione; non avete diversion
o regole di visibilit&agrave; (scoping), ecc.

CPP si trova assieme ad ogni compilatore C. Se ve la siete cavata senza
averne uno, non preoccupatevi di procurarvi GCC (anche se mi chiedo come
abbiate fatto).

<sect2>M4
<p>
M4 vi d&agrave; tutta la potenza delle macro,
con un linguaggio Turing-equivalente, ricorsione, espressioni regolari,
ecc.
Potete farci tutto ci&ograve; che CPP non riesce a fare.

Date un'occhiata a macro4th/This4th da
	<url url="ftp://ftp.forth.org/pub/Forth/"> in Reviewed/ ANS/ (?),
o le sorgenti di Tunes 0.0.0.25 come esempi di
un utilizzo avanzato delle macro con m4.
Comunque, il suo scomodo sistema di protezione dall'espansione vi obbliga
ad utilizzare per le macro uno stile basato sulla ricorsione in coda con
passaggio di continuazione esplicito (explicit continuation-passing) se
volete una uso <em/avanzato/ delle macro
(il che ricorda TeX. A proposito, qualcuno ha provato ad usare TeX per le
macro di qualcosa di diverso dalla composizione tipografica?).
Questo comunque NON &egrave; peggio di CPP, il quale non permette
n&eacute; il quoting n&eacute; la ricorsione.
La versione giusta di m4 da procurarsi &egrave; GNU m4 1.4 (o successiva,
se esiste), la quale ha il maggior numero di funzionalit&agrave; ed il minor
numero di bug o limitazioni rispetto alle altre.
m4 &egrave; progettato per essere lento per tutto tranne gli utilizzi
pi&ugrave semplici, il che potrebbe andare ancora bene per la maggior
parte dei programmi assembly
(non state scrivendo programmi in assembly da milioni di righe, vero?).


<sect2>Macro con i vostri filtri
<p>
Potete scrivervi dei semplici filtri per l'espansione delle macro
con i soliti strumenti: perl, awk, sed, ecc.
Si fa in fretta ed avete il controllo su tutto.
Ma ovviamente, la potenza nella gestione delle macro bisogna guadagnarsela
con fatica.


<sect2>Metaprogrammazione
<p>
Invece di usare un filtro esterno che espande le macro,
un modo alternativo di procedere &egrave; quello di scrivere programmi che
scrivono parti di altri programmi (o interi programmi).

Ad esempio, potreste utilizzare un programma che dia in uscita codice
sorgente
<itemize>
<item>
per generare tavole precalcolate di seno/coseno/quant'altro,
<item>
per estrarre una rappresentazione in forma sorgente di un file binario,
<item>
per inserire le vostre bitmap nel codice compilato di routine di
visualizzazione rapide,
<item>
per estrarre documentazione, codice di inizializzazione/conclusione,
tabelle di descrizione cos&igrave; come codice ordinario dagli stessi
file sorgenti,
<item>
per avere codice assembly personalizzato, generato da uno script
perl/shell/scheme che si occupa di elaborazione generica. 
<item>
per propagare dati definiti in un punto solo verso vari pezzi di codice e
tabelle con riferimenti incrociati.
<item>
ecc.
</itemize>

Pensateci!


<sect3>Backend da compilatori esistenti
<p>
Compilatori come SML/NJ, Objective CAML, MIT-Scheme, ecc.
hanno il loro backend generico per gli assemblatori
che potreste o meno voler usare se intendete generare
semiautomaticamente del codice partendo dai linguaggi relativi.


<sect3>Il New-Jersey Machine-Code Toolkit
<p>
C'&egrave; un progetto per costruire, usando il linguaggio di
programmazione Icon, una base per produrre codice che manipola
l'assembly. Date un'occhiata dalle parti di
	<url url="http://www.cs.virginia.edu/&tilde;nr/toolkit/">


<sect3>Tunes
<p>
Il progetto Tunes OS sta sviluppando il suo
assemblatore come un'estensione al linguaggio Scheme,
come parte del suo processo di sviluppo.
Al momento non &egrave; ancora in grado di girare, tuttavia ogni
aiuto &egrave; bene accetto.

L'assemblatore manipola alberi di sintassi simbolici,
cos&igrave; pu&ograve; ugualmente servire come base per un traduttore
di sintassi assembly, un disassemblatore, un backend comune per
assemblatore/compilatore, ecc.
Inoltre tutta la potenza di un vero linguaggio, Scheme, lo rende
insuperato per quanto riguarda le macro e la metaprogrammazione.

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




<sect>CONVENZIONI DI CHIAMATA
<p>


<sect1>Linux
<p>

<sect2>Linking a GCC
<p>
&Egrave; il modo preferito.
Controllate la documentazione di GCC e gli esempi dai file <tt/.S/
del kernel di Linux che passano attraverso gas (non quelli che passano
attraverso as86).

Gli argomenti a 32 bit vengono posti sullo stack (push) in ordine inverso
rispetto alla sintassi (per cui vi si accede prelevandoli
nell'ordine corretto) sopra l'indirizzo di ritorno a 32 bit.
<tt/&percnt;ebp/, <tt/&percnt;esi/,
<tt/&percnt;edi/, <tt/&percnt;ebx/ sono salvati dalla funzione chiamata,
gli altri dalla funzione chiamante;
per contenere il risultato si usa <tt/&percnt;eax/,
oppure <tt/&percnt;edx:&percnt;eax/ per risultati a 64 bit.

Stack FP: non ne sono certo, ma penso che il risultato vada
in <tt/st(0)/ e che l'intero stack sia salvato dalla funzione chiamante.
Notate che GCC ha delle opzioni per modificare le convenzioni di chiamata
riservando registri, per mettere argomenti nei registri, per non
fare supposizioni sulla presenza dell'FPU, ecc.
Controllate le pagine .info i386 .

Fate attenzione: in questo caso dovete dichiarare l'attributo <tt/decl/
per una funzione che seguir&agrave; le convenzioni di chiamata
standard di GCC (non so cosa faccia con le convenzioni di chiamata modificate).
Leggete le pagine info di GCC nella sezione:
	<tt/C Extensions::Extended Asm::/



<sect2>ELF ed a.out : problemi.
<p>
Alcuni compilatori C antepongono un underscore prima di ogni simbolo,
mentre altri non lo fanno.

In particolare, GCC a.out per Linux effettua questa anteposizione,
mentre GCC ELF per Linux no.

Se avete bisogno di gestire insieme entrambi i comportamenti,
guardate come fanno i pacchetti esistenti.
Ad esempio, procuratevi dei vecchi sorgenti di Linux,
Elk, qthreads, o OCAML...

Potete inoltre far ignorare la rinominazione implicita C<tt/-&gt;/asm
inserendo istruzioni come
<code>
	void pippo asm(&dquot;pluto&dquot;) (void);
</code>
per essere sicuri che la funzione C «pippo» venga chiamata davvero
«pluto» in assembly.

Notate che il programma di utilit&agrave; <tt>objcopy</tt>, dal pacchetto
<tt>binutils</tt>, dovrebbe permettervi di trasformare i vostri oggetti
a.out in oggetti ELF e forse anche viceversa, in alcuni casi.
Pi&ugrave; in generale, effettuer&agrave; un gran numero di conversioni
di formato dei file.



<sect2>Linux: chiamate di sistema dirette
<p>
Ci&ograve; &egrave; espressamente <em/NON/ consigliato,
poich&eacute; le convenzioni cambiano di tanto in tanto
o tra varianti del kernel (vedere L4Linux),
inoltre si perde la portabilit&agrave;, comporta un lavoro
di scrittura massiccio, si ha ridondanza con gli sforzi di libc ED INOLTRE
preclude estensioni e correzioni apportate a libc come, ad esempio,
il pacchetto <tt>zlibc</tt>, che provvede ad una trasparente decompressione
«al volo» di file compressi con gzip.
Il metodo convenzionale e consigliato per chiamare i servizi di sistema
di Linux &egrave;, e rimarr&agrave;, quello di passare attraverso la libc.

Gli oggetti condivisi dovrebbero mantenere la vostra roba entro
dimensioni contenute.
E se proprio volete binari pi&ugrave; piccoli, utilizzate <tt>&num;!</tt>
e scaricate sull'interprete il fardello che volete togliere dai vostri
binari.

Ora, se per qualche ragione non volete fare un link alla libc,
procuratevi la libc stessa e capite come funziona!
Dopotutto, aspirate a sostituirla, no?

Potreste inoltre dare un'occhiata a come il mio
	<url url="ftp://ftp.forth.org/pub/Forth/Linux/linux-eforth-1.0c.tgz"
		name="eforth 1.0c">
lo fa.

Anche i sorgenti di Linux tornano utili,
in particolare l'header file asm/unistd.h,
che descrive come effettuare le chiamate di sistema...

Fondamentalmente, generate un <tt>int &dollar;0x80</tt>,
con il numero associato a <tt/&lowbar;&lowbar;NR&lowbar;/nomedellasyscall
(da <tt>asm/unistd.h</tt>) in <tt/&percnt;eax/,
ed i parametri (fino a cinque) in
<tt/&percnt;ebx/, <tt/&percnt;ecx/, <tt/&percnt;edx/,
<tt/&percnt;esi/, <tt/&percnt;edi/ rispettivamente.
Il risultato viene restituito in <tt>&percnt;eax</tt>,
dove un numero negativo &egrave; un errore
il cui opposto &egrave; ci&ograve; che libc metterebbe in errno.
Lo stack utente non viene toccato,
cos&igrave; non &egrave; necessario averne uno valido quando effettuate
una chiamata di sistema.


<sect2>I/O sotto Linux
<p>
Se volete effettuare dell'I/O sotto Linux,
o si tratta di qualcosa di molto semplice che non richiede l'arbitraggio
del sistema operativo, e allora dovreste consultare
l'<tt/IO-Port-Programming mini-HOWTO/,
oppure ha bisogno di un driver di periferica nel kernel, nel qual
caso dovreste provare ad approfondire le vostre conoscenze sull'hacking
del kernel, sullo sviluppo di driver di periferica, sui moduli del
kernel, ecc., per i quali ci sono altri
eccellenti HOWTO e documenti del LDP.

In particolare, se ci&ograve; che vi interessa &egrave; la programmazione
della grafica, allora partecipate al progetto GGI:
	<url url="http://synergy.caltech.edu/&tilde;ggi/">
	<url url="http://sunserver1.rz.uni-duesseldorf.de/&tilde;becka/doc/scrdrv.html">

Comunque, in tutti questi casi, fareste meglio ad usare l'assembly inline
di GCC con le macro da linux/asm/*.h piuttosto che scrivere file sorgenti
completamente in assembly.

<sect2>Accedere a driver a 16 bit da Linux/i386
<p>
Ci&ograve; &egrave; teoricamente possibile
(dimostrazione: guardate come DOSEMU riesca a garantire ai programmi un accesso
a porte hardware in modo selettivo), ed ho anche sentito voci secondo le quali
qualcuno da qualche parte ci sarebbe di fatto riuscito (nel driver PCI?
Roba per l'accesso VESA? ISA PnP? Non so).
Se avete informazioni pi&ugrave; precise a riguardo, siate i benvenuti.
Comunque, buoni posti in cui cercare maggiori informazioni sono i sorgenti
del kernel di Linux, i sorgenti di DOSEMU (ed altri programmi nel
<url url="ftp://tsx-11.mit.edu/pub/linux/ALPHA/dosemu/"
     name="DOSEMU repository">),
e sorgenti di vari programmi a basso livello sotto Linux...
(forse GGI se supporta VESA).
Fondamentalmente, dovete usare la modalit&agrave; protetta a 16 bit
o il modo vm86.

Il primo &egrave; pi&ugrave; semplice da mettere in piedi, ma funziona
solamente con codice «educato» (well-behaved) che non utilizza l'aritmetica
dei segmenti o indirizzamento assoluto degli stessi (segmento 0 in
particolare), a meno che non ci si trovi nel caso in cui tutti i segmenti
utilizzati possano essere preparati in anticipo nella LDT.

Il secondo permette pi&ugrave; «compatibilit&agrave;» con i comuni ambienti
a 16 bit, ma richiede una gestione pi&ugrave; complessa.

In entrambi i casi, prima di poter saltare al codice a 16 bit,
dovete
<itemize>
<item>fare un mmap di tutti gli indirizzi assoluti utilizzati nel codice a
16 bit
(come ROM, buffer video, zone su cui agir&agrave; il DMA
ed I/O memory-mapped)
da /dev/mem allo spazio indirizzi del vostro processo.
<item>preparare la LDT e/o il monitor per il modo vm86
<item>ottenere gli opportuni permessi di I/O dal kernel (vedere sopra)
</itemize>

Ancora una volta, leggete con cura i sorgenti dei contributi al DOSEMU
repository menzionato sopra,
in particolare quei mini-emulatori per far girare ELKS e/o semplici
programmi .COM sotto Linux/i386.

<sect1>DOS
<p>
La maggior parte dei DOS extender viene fornita con dell'interfacciamento
a servizi DOS.
Leggete la loro documentazione a riguardo, ma spesso si limitano a simulare
<tt/int &dollar;0x21/ e simili, cos&igrave; vi comportate «come se»
foste in modo reale
(dubito che abbiano qualcosa di pi&ugrave; di stub
ed estensioni per lavorare con operandi a 32 bit;
molto probabilmente si limiteranno a riportare l'interrupt
nel gestore del modo reale o del vm86).

Documentazione su DPMI e affini (e molto pi&ugrave;) pu&ograve; essere
trovata in
	<url url="ftp://x2ftp.oulu.fi/pub/msdos/programming/">

Anche DJGPP viene fornito con il proprio derivato/sottoinsieme/sostituto di
glibc.

&Egrave; possibile la compilazione incrociata da Linux a DOS,
guardate nella directory devel/msdos/ del vostro mirror locale dell'area
FTP di sunsite.unc.edu
Date anche un'occhiata al DOS extender «MOSS» dal progetto Flux in Utah.

Altri documenti e FAQ sono molto DOS-centrici.
Noi non consigliamo di sviluppare per DOS.


<sect1>Winzozz e compagnia bella
<p>
Ehi, questo documento riguarda solo il software libero.
Telefonatemi quando Winzozz diventa libero,
o ci si possono usare strumenti di sviluppo liberi!

Beh, dopotutto ci sono:
<url url="http://www.cygnus.com" name="Cygnus Solutions">
ha sviluppato la libreria cygwin32.dll
per far girare i programmi GNU su piattaforme Micrashoft.
Cos&igrave; potete usare GCC, GAS, tutti gli strumenti di GNU
e molte altre applicazioni UNIX.
Date un'occhiata alla loro homepage.
Io (Far&eacute;) non intendo dilungarmi sulla programmazione di WinnaNanna
ma sono certo che potete trovare un sacco di documentazione a riguardo
praticamente ovunque...


<sect1>Un sistema operativo tutto vostro.
<p>
Essendo il controllo ci&ograve; che attrae molti programmatori all'assembly,
il desiderio di sviluppare sistemi operativi &egrave; spesso ci&ograve; che
li porta all'(o deriva dall') hacking in assembly.
Va notato che ogni sistema che permette lo sviluppo di se stesso
potrebbe essere considerato un «sistema operativo», anche se magari
gira «sopra» ad un sistema sottostante che fornisce multitasking o I/O (in
modo molto simile a Linux sopra Mach o OpenGenera sopra UNIX), ecc.

<!-- -->
Quindi, per rendere pi&ugrave; facile il debugging,
potreste voler sviluppare il vostro «sistema operativo» prima come
processo che gira sopra a Linux (nonostante la lentezza), quindi usare il
<url url="http://ww.cs.utah.edu/projects/flux/" name="Flux OS kit">
(che consente l'utilizzo di driver di Linux e BSD nel vostro OS)
per renderlo autonomo.
Quando il vostro sistema &egrave; stabile,
resta ancora del tempo per scrivere dei driver
per l'hardware tutti vostri, se la cosa vi fa proprio piacere.

Questo HOWTO non si occuper&agrave; di argomenti quali
il codice per il boot loader ed entrare nel modo a 32 bit,
gestire gli interrupt, i fondamenti degli orrori intel
«modo protetto» o «V86/R86», la definizione di un vostro formato per i
file oggetto e le convenzioni di chiamata.
<!-- -->
Il luogo principale in cui trovare informazioni attendibili a riguardo
sono i sorgenti di sistemi operativi o bootloader gi&agrave; esistenti.
Ci sono un sacco di riferimenti in questa pagina WWW:
    <url
    url="http://www.eleves.ens.fr:8080/home/rideau/Tunes/Review/OSes.html"
    >


<sect>COSE DA FARE E RIFERIMENTI
<p>

<itemize>
<item>riempire le sezioni incomplete.
<item>aggiungere ulteriori riferimenti a software e documentazione.
<item>aggiungere esempi facili dal mondo reale per illustrare la sintassi,
la potenza e le limitazioni di ogni soluzione proposta.
<item>chiedere aiuto in giro per questo HOWTO.
<item>trovare qualcuno che ha del tempo per subentrarmi nel mantenimento.
<item>che sia il caso di spendere qualche parola sull'assembly su altre
piattaforme?

<item>Alcuni riferimenti (in aggiunta a quelli gi&agrave; presenti nel resto
dell'HOWTO)
<itemize>
<item><url url="http://www.intel.com/design/pentium/manuals/"
		name="i manuali del pentium">
<item><url url="http://www.xs4all.nl/&tilde;feldmann"
	   name="bug nelle CPU della famiglia x86">
<item><url url="http://www.eng.ufl.edu/ftp"
	   name="hornet.eng.ufl.edu per programmatori assembly">
<item><url url="ftp://ftp.luth.se/pub/msdos/demos/code/"
	   name="ftp.luth.se">
<item><url url="ftp://zfja-gate.fuw.edu.pl/cpu/protect.mod"
           name="FAQ del modo protetto">
<item><url url="http://www.fys.ruu.nl/&tilde;faber/Amain.html"
	   name="Pagina dell'assembly 80x86">
<item><url url="http://www.cit.ac.nz/smac/csware.htm"
	   name="Courseware">
<item><url url="http://www.ee.ucl.ac.uk/&tilde;phart/gameprog.html"
 	   name="programmazione di giochi">
<item><url url="http://bewoner.dma.be/JanW"
	   name="esperimenti di programmazione solo in assembly sotto Linux">
</itemize>
<item>E ovviamente, utilizzate i vostri strumenti di ricerca su Internet per
cercare ulteriori informazioni e ragguagliatemi su qualunque cosa interessante
troviate!

</itemize>


<!--FOOTER-->
.sig dell'autore:
<verb>
--    ,                                         ,           &lowbar; v    &tilde;  ^  --
-- 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/
</verb>
</article>




