Sezione

Indirizzi Base Registri Interni
Area Comunicazione BIOS Funzioni BIOS Funzioni DOS
Prefazione Capitolo 1 Capitolo 2 Schede
Libreria ASM Libreria MAC Palestra Progetti ASM
Info Download INDICE

Capitolo 2

Home » Programma il Computer » Tutorial Assembly

Capitolo 2 - Gli strumenti di lavoro

  Gli strumenti di Lavoro

ASSEMBLATORE 2/17 [21 di 87] 

    

  

Aggiornato 18 settembre 2006

    Come l'Assemblatore traduce il codice Sorgente?
     
bulletIl programma assemblatore (detto anche semplicemente assembler) è un oggetto fondamentale ed indispensabile; nulla può essere verificato senza la sua disponibilità.

      

bulletIl compito principale dell’assemblatore è quello di tradurre il testo Ascii (codice sorgente, ASM, o codice assembly) che abbiamo appena prodotto in ambiente Editor nel corrispondente codice oggetto, OBJ, analizzando con cura le singole parole per controllarne forma e sostanza (sintassi).

      

bulletPoiché è impensabile che il programmatore sviluppi un applicativo in codice macchina, ogni microprocessore deve avere un traduttore adatto a trasformare le stringhe mnemoniche dell'assembly nei corrispondenti codici macchina.

      

Ricorda... Questa premessa è una buona occasione per distinguere, una volta per tutte, 2 parole spesso erroneamente utilizzate in modo intercambiabile; non si tratta di un peccato particolarmente grave, ma vale la pena distinguere:
punto elenco assembly è l'insieme delle stringhe mnemoniche utilizzate nel programma sorgente per creare il programma ASM: in concreto è il linguaggio usato per programmare i processori e, per questa caratteristica essenziale, è detto anche a basso livello.
punto elenco assembler è invece lo strumento che consente di tradurre le istruzioni assembly nel codice macchina cioè nella sequenza di numeri binari (bytes) da dare in pasto al processore; si tratta dunque di un programma eseguibile, detto appunto assemblatore per questa sua specificità.

      

bulletNaturalmente ogni processore parla un dialetto diverso dai suoi simili: tutti comunicano con gli stessi numeri esadecimali compresi tra 00H e FFH (bytes) ma quasi certamente al medesimo numero fanno corrispondere una funzione diversa.
bulletUna vera e propria Babele informatica che molto frequentemente si manifesta anche in piccole, ma fastidiose, differenze tra gli mnemonici, anche a livello assembly.

      

Ricorda... Il programmatore non ama cambiare processore: dopo aver imparato con golosità le stringhe mnemoniche del suo linguaggio assembly, le usa con accanimento, le gira e le rigira...
Quando è costretto a cambiare, guarda con sospetto le nuove stringhe, le confronta con le precedenti e maledice intimamente le differenze, ma alla fine, con molta riluttanza, le accetta rassegnato... e tutto continua come prima.

      

bulletIl meccanismo usato da un assemblatore per tradurre le stringhe in numeri è piuttosto semplice e ripetitivo; esso contiene delle tabelle di conversione, con tutte le "paroline" (mnemonici) da una parte e i numeri esadecimali corrispondenti (codici operativi) dall'altra.

      

bulletEsso analizza le righe di codice di ogni stringa mnemonica (istruzione, codice assembly) associa loro una sequenza di bytes (codice macchina) e un numero progressivo a 16 bit (indirizzo corrente); quest'ultimo serve per localizzare con certezza l'inizio di determinati gruppi di istruzioni a cui il programma desidera riferirsi (o saltando in quel punto o chiamando il gruppo).

      

bulletTutto ciò è chiaramente visibile facendo analizzare il nostro programma da Debug.
bulletL'esempio di codice assembly proposto come fil rouge pur essendo molto semplice può aiutare a capire il funzionamento dell'assemblatore; lo riportiamo per comodità qui di seguito:

      

_prog   SEGMENT BYTE PUBLIC 'CODE'
        ASSUME CS:_prog,DS:_prog
        ORG    0100H

INIZIO: JMP    Main

KeyWait:MOV    AH,00H   ;Aspetta la pressione
        INT    16H      ;di un tasto
        RET             ;

BiosCls:MOV    AH,00H   ;
        MOV    AL,03H   ;Pulisci lo schermo
        INT    10H      ;(ClearScreen)
        RET             ;

Main:   CALL   BiosCls  ;
        CALL   KeyWait  ;Chiama le procedure
        MOV    AH,4CH   ;e poi torna al dos
        INT    21H      ;
_prog   ENDS
        END
INIZIO

      

bullet Notiamo subito che non ci sono riferimenti irrisolti, cioè tutte le etichette coinvolte come operando nelle istruzioni (presenti a destra dei rispettivi mnemonici, nell'esempio JMP e CALL) sono definite dentro il codice ASM, come previsto, nella prima colonna a sinistra (vedremo che, in caso contrario, sarà necessario coinvolgere la direttiva EXTRN per assicurare la compilabilità del programma).
bulletIn ogni caso l'indirizzo iniziale dal quale comincia la compilazione è di norma indicato dalla direttiva ORG: nel nostro esempio (ORG 0100H) il primo byte della prima istruzione sarà dunque associato all'indirizzo 0100H (pari a 256, in decimale, sebbene convenga abituarsi a considerare irrilevante questa precisazione), valore con cui sarà caricato anche il contatore di programma, cioè il registro IP (Instruction Pointer) con cui la CPU punterà le istruzioni da eseguire. Vediamo che cosa succede:
bulletprima istruzione (INIZIO: JMP Main):  
bulletl'assemblatore riconosce la parola INIZIO come etichetta e le associa subito il valore corrente del contatore (0100H).
bulletla parola che segue (JMP, salto) deve essere contenuta nella  tabella di conversione: naturalmente la trova e le associa subito il numero (codice operativo) E9H o EBH di solito ad essa associato
bulletpoiché sa che la parola JMP corrisponde ad un'istruzione che ha bisogno di un operando che esprime un indirizzo, annota la parola che segue (Main) e poiché non conosce ancora il numero esadecimale a 16 bit che le corrisponde (deve ancora trovare l'etichetta con il medesimo nome) la traduce momentaneamente con i 2 bytes 00H, 00H; l'istruzione è comunque codificata con 3 bytes 
bullet come decritto qui in dettaglio, è curioso osservare come l'assemblatore sia in grado di capire (prima di ultimare il suo lavoro) se si tratta di un salto vicino (NEAR, nel range 32767 in avanti e 32768 indietro) o corto (SHORT, nel range 127 in avanti e 128 indietro)
bulletnel primo caso l'istruzione è codificata con codice operativo E9H seguito da una word con segno
bulletnel secondo caso l'istruzione è codificata con codice operativo EBH seguito da un byte con segno; poichè il terzo bytes previsto dal codice mnemonico non è necessario, l'assemblatore lo codifica con 90H, NOP.
bulletin entrambi i casi  sia la word che il byte esprimono il numero di locazioni da saltare in avanti o indietro per raggiungere la locazione associata all'etichetta  (Main, nel nostro caso)
bulletpoiché sa che l'istruzione JMP Main è comunque codificata con 3 bytes  (E9H, loH, hiH o EBH, xyH, 90H) aggiorna il contatore portandolo al valore 0103H (appunto 0100H + 3)
bulletseconda istruzione (KeyWait: MOV AH,00H ;Aspetta la pressione):  
bulletla parola KeyWait è riconosciuta come etichetta: l'assemblatore le associa subito il numero corrente del contatore (0103H).
bulletla parola che segue (MOV) viene trovata in tabella; l'assemblatore capisce che si tratta di un'istruzione che ha diverse possibilità di codifica e stabilisce il corretto codice operativo in funzione dei 2 operandi che seguono: se le parole che seguono sono AH,00H il codice operativo che corrisponde alla stringa è B4H e il secondo operando è numerico, il byte 00H.
bulletnella analisi della riga di istruzione trova ;Aspetta la pressione, ma non cerca di interpretarne il significato perchè è istruito ad ignorare qualunque stringa Ascii successiva a ; (punto e virgola), ritenendola un commento.
bulletpoiché sa che l'istruzione MOV AH,00H è esprimibile con 2 bytes (B4H, 00H) aggiorna il contatore portandolo al valore 0105H (appunto 0103H + 2).
bulletTutte le altre istruzioni sono trattate con la medesima filosofia.

      

Suggerimento L'assemblatore si comporta dunque in modo esattamente duale rispetto al processore che rappresenta: quando sarà chiamata a leggere, interpretare ed eseguire il codice macchina finale, la CPU farà le stesse cose:
terrà aggiornato un contatore (il suo registro IP, Instruction Pointer) per puntare di volta in volta i bytes che esprimono un'istruzione
capirà dal codice operativo quanti (eventuali) bytes operandi dovranno essere interpretati dopo di esso, come dovranno essere coinvolti nell'esecuzione e di quanti bytes dovrà essere aumentato il contatore d'istruzione.

    

Pagina Precedente Capitolo 2 Pagina Successiva ASSEMBLATORE 2/17   Torna alla Home  del Capitolo1 del "Tutorial" Lezioni - Vai al DownLoad dei files DOC Torna al Menu del "Tutorial"
21 di 87
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

    

CAP 2 » 1. Catena di Compilazione 2. Editor 3. Assemblatore 4. Linker 5. Exe2Bin
6.
Ambiente di Lavoro 7. Gestore d'Ambiente Macro 8. Gestore d'Archivi OG
9. Matrici per i Programmi Sorgente 10. Gestore di Librerie Lib 
TUTORIAL » Indirizzi Base | Registri Interni | Area Comunicaz. BIOS | Funzioni BIOS | Funzioni DOS
Prefazione | CAP 1 | CAP 2 | Schede | Palestra
Libreria ASM | Libreria MAC | Progetti ASM | Download | Info | Indice
Home 
Pascal|Manuali|Tabelle|Schede
Tutorial Assembly|Palestra Assembler
Aggiungi Giobe®2000 ai preferiti  
Motore
Ricerca
  Rendi Giobe®2000 pagina di Default
© 2001-2010  -  Studio Tecnico ing. Giorgio OBER
Tutti i diritti sono riservati