L'assemblatore AT&T per linux si chiama as o GAS e fa parte del pacchetto gcc; essendo tale pacchetto disponibile per le piattaforme Windows, con il nome di cygwin, è possibile usare as anche in tale ambiente.
I sorgenti scritti con questo linguaggio hanno per convenzione l'estensione «.s» ma è possibile scegliere qualsiasi altro tipo di nome.
Per assemblare un sorgente si deve eseguire il comando:
$
as -a -o nome_oggetto.o nome_sorgente.s
L'opzione -o serve ad indicare il nome del file oggetto ottenuto con la traduzione; essa però si conclude positivamente solo se non vengono riscontrati errori di sintassi dei quali eventualmente si riceve opportuna segnalazione (descrizione dell'errore e indicazione della riga in cui è avvenuto).
L'opzione -a non è obbligatoria e ha lo scopo di ottenere a video il sorgente affiancato dalla traduzione in codice macchina delle istruzioni e seguito dalle liste dei simboli (etichette dati e istruzioni); il fatto che tali informazioni vengano rese disponibili a video permette di poterle eventualmente ridirezionare su un file per un loro più comodo esame.
Altra opzione importante è --gstabs che costringe l'assemblatore a inserire maggiori informazioni all'interno del file oggetto; tali informazioni sono indispensabili se si vogliono usare programmi debugger come gdb, che è il più usato in ambiente GNU/Linux.
Una volta concluso il collaudo del programma ed eliminati tutti gli errori, è però consigliabile assemblare il programma senza l'opzione --gstabs in modo da avere un file oggetto, e quindi un eseguibile, più snello e con migliori prestazioni.
Per avere dettagli sulle molte altre opzioni disponibili si può eseguire il comando:
$
man as
Se si lavora con una CPU a 64 bit ma si vuole ottenere un programma oggetto a 32 bit si deve aggiungere l'opzione --32 al comando as. |
Per ottenere l'eseguibile occorre usare il programma per il linking ld nel modo seguente:
$
ld -o nome_eseguibile nome_oggetto.o
L'opzione -o permette di indicare il nome del file eseguibile.
Anche questo comando prevede molte opzioni e inoltre offre la possibilità di fare il linking di più file oggetto contemporaneamente; nei prossimi capitoli sfrutteremo alcune sue potenzialità esaminando programmi sempre più complessi.
Ovviamente è anche qui possibile consultare il manuale in linea con:
$
man ld
Per eseguire il programma occorre il comando:
$
./nome_eseguibile
oppure:
$
/percorso_per_raggiungere_eseguibile/nome_eseguibile
L'esecuzione di un programma scritto in assembly non sempre offre risultati che possono essere apprezzati direttamente; questo accade soprattutto quando si inizia a usare il linguaggio e quindi non si usano istruzioni per l'input e l'output.
Può inoltre capitare che, in presenza di risultati visibili da parte del programma, questi non coincidano con quelli attesi oppure che il programma abbia comportamenti imprevisti e strani; in tal caso siamo in presenza di errori run-time o di errori logici.
In entrambe queste situazioni diventa indispensabile l'uso di un debugger come gdb in modo da poter inserire dei breakpoint che permettono poi l'esecuzione passo dopo passo, e da poter visionare il contenuto della memoria e dei principali registri.
Per attivarlo si deve dare il comando:
$
gdb nome_eseguibile
Ci troviamo in questo modo nell'ambiente interattivo di gdb cha ha un suo prompt:
|
e mette a disposizione una serie di comandi come:
q: esce dall'ambiente gdb;
h: aiuto sui comandi gdb;
l: lista alcune righe del sorgente;
l num_riga: lista le righe del sorgente subito prima e subito dopo quella indicata;
info address var: restituisce l'indirizzo di var;
info variables: restituisce nome e indirizzo di tutte le variabili;
info registers: visualizza lo stato dei registri;
breakpoint num_riga: inserisce un blocco subito dopo la riga indicata;
r: esegue il programma fino al primo blocco;
c: riprende l'esecuzione;
s: esegue solo l'istruzione successiva.
Per maggiori dettagli si può consultare il manuale del comando gdb, che è comunque uno strumento abbastanza ostico anche se molto potente.
Per facilitare il compito ai programmatori assembly sono stati allora creati vari programmi che sono delle interfacce grafiche di gdb; esempi in tal senso possono essere ddd e insight.
Sono entrambi strumenti abbastanza semplici e intuitivi e per il loro uso dovrebbe essere sufficiente la consultazione dei rispettivi manuali on-line; di ddd vedremo esempi di utilizzo nei prossimi paragrafi.
Si ricorda in ogni caso che per poter usare questi programmi occorre avere assemblato il sorgente con l'opzione --gstabs.
Si può anche usare gcc in alternativa ad as per la traduzione del sorgente assembly; in questo caso il comando da lanciare è:
$
gcc -c -g -o nome_oggetto.o nome_sorgente.s
L'opzione -o ha il ruolo già illustrato in precedenza, l'opzione -c fa si che gcc si fermi alla creazione del file oggetto senza procedere con il linking e l'opzione -g (ovviamente facoltativa) ha lo stesso scopo di --gtabs quando si usa as.
Infine vediamo che è anche possibile fare tutto (traduzione e linking) con gcc con il comando:
$
gcc -g -o nome_eseguibile nome_sorgente.s
però in questo caso la parte esecutiva del programma deve iniziare con l'etichetta main: al posto di _start:; questo aspetto sarà forse più chiaro al momento in cui vedremo la struttura del sorgente assembly AT&T (paragrafo 3.4):
Quando si compila un programma sorgente in linguaggio c con il comando:
otteniamo come risultato il programma eseguibile (se non ci sono errori); in realtà però avviene un doppio passaggio realizzato da gcc:
Il file oggetto temporaneo è un file in linguaggio macchina del tutto analogo a quello che si ottiene quando si assembla un sorgente .s. Se si vuole vedere il codice assembly corrispondente all'oggetto creato da gcc quando compila un sorgente c, occorre eseguire il comando:
e si ottiene come risultato il listato assembly in nome_sorgente.s. |
Se si lavora con una CPU a 64 bit ma si vuole ottenere un programma eseguibile a 32 bit si deve aggiungere l'opzione -m32 al comando gcc (in tal caso deve essere installato il pacchetto gcc-multilib). |