La nascita dell’Assembly Il microprocessore comprende solo un tipo di linguaggio, il Linguaggio Macchina, ovvero una sequenza di 0 e 1 molto difficile da leggere. Per ridurre le difficoltà i programmatori hanno, fin dall’inizio, adoperato la base esadecimale anziché quella binaria. La situazione è migliorata quando è stato creato un primo linguaggio più comprensibile all’uomo, dove, al posto dei codici operativi in esadecimale, sono stati impiegati dei codici mnemonici. codice esadecimale Æ 05 = ADD Å codice mnemonico È nato così il linguaggio Assembly. 1 Ma non si dice Assembler? L’Assembly è il linguaggio, e il codice è un codice Assembly. L’Assembler è un programma che trasforma il codice scritto in Assembly in codice Linguaggio Macchina (una forma di traduttore). comunque è tollerato l’errore di confondere l’Assembly con Assembler: spesso, infatti, si sente parlare di programma scritto in linguaggio Assembler 2 Non esiste un unico Assembly Ogni CPU ha un Assembly diverso perché diversi sono i codici operativi per le varie CPU. … MA … Anche per le stesse CPU (noi lavoreremo con CPU INTEL) i programmi Assembly possono essere leggermente diversi fra di loro. Vediamone la causa: Alcune differenze dipendono dal prodotto che impieghiamo per scrivere in Assembly: Nel nostro caso impieghiamo il TASM ma vi sono altri Assembly come il MASM oppure AsmStudio e altri ancora… Altre differenze dipendono dal Sistema Operativo in cui operiamo: ad esempio il fatto che il DOS sia un S.O. a 16 bit mentre WINDOWS è un S.O. a 32 bit ci fa comprendere che, necessariamente, i programmi devono essere scritti con modalità diverse. Noi impiegheremo l’Assembly per sviluppare programmi in DOS 3 Perché DOS? Perché il funzionamento di un Assembly per DOS / INTEL è molto simile a un Assembly per un altro S.O. / CPU … ma soprattutto … Perché lo scopo di queste lezioni non è quello di programmare in Assembly, bensì quello di comprendere il funzionamento di una CPU (e quindi del computer). 4 Come è fatto un programma DOS? Un programma DOS è diviso in 1 o più segmenti. Cosa è un segmento? Un segmento è una parte di memoria che può comprendere fino a 65.536 celle (e quindi 65.536 bytes ovvero 64KB, poiché ogni cella dei nostri computer contiene 1 byte) Un programma DOS, infatti, accede alla memoria secondo questa logica di indirizzi: 5 Considerazioni sulla Memoria Questa modalità di indirizzamento: 09 F4 : A5 7B ci fa comprendere che la memoria può essere vista dal DOS come fino a un massimo di 65.536 segmenti ognuno dei quali può contenere fino a 65.536 celle … … e, visto che ogni cella contiene 1 byte, un computer DOS riesce a vedere fino a 4.294.967.296 di bytes di memoria centrale. Questo limite vale anche per i S.O. Windows (NT, 2000, XP, …) 6 La Memoria Centrale 7 Limite dei programmi DOS Il DOS ha un forte limite: tutto il codice del programma (stiamo parlando del programma in linguaggio macchina) può essere contenuto solo in un segmento, quindi non può superare i 64KB. Questo limite non esiste per i S.O. più recenti. 8 Ma cosa è un programma? Un programma è una sequenza di operazioni che si chiede al computer di eseguire. Un programma è, quindi, costituito da un insieme di istruzioni ordinate che vengono eseguite una dopo l'altra. riga di istruzione del programma MOV AX BX Il componente della macchina di Von Neumann che fattivamente esegue il programma è la: CPU (Central Processing Unit) 9 Programma È la CPU, quindi, che ha il compito di eseguire un programma. riga di istruzione del programma MOV Codice Operativo (operatore) AX Indirizzo I° operando BX Indirizzo 2° operando La CPU 80x86 è una macchina a due indirizzi. Questo significa che una riga di istruzione è formata normalmente dal codice operativo e due operandi. 10 La CPU 80x86 Intel a 16 bit di 48 bit CPU Central Processing Unit Registro della Istruzione IR CU Unità di Controllo (in esecuzione) AX BX CX DX Accumulatori SP BP IP Registri Pointer SI DI Registri di indirizzamento indiretto di 16 bit ALU Unità Logico Aritmetica abbiamo visto che le CPU 80x86 sono macchine a due indirizzi e quindi il registro IR è formato da 16*3 bit. Infatti: • 2 byte sono per l’operatore; • 2 byte per il I° operando; • 2 byte per il 2° operando. CS DS SS ES di 8 bit Registri General Pourpose puntatore alla prossima istruzione da eseguire segmento del codice (del programma) Registri di Segmento segmento dei dati carry SR zero Registro di Stato bit di segno overflow 11 Accesso ai registri Nella programmazione in Assembly si accede ai registri con i mnemonici AX, BX, ecc … e quindi direttamente ai 2 byte (16 bit) di cui è composto il registro … MA … è anche possibile accedere a uno solo dei due byte usando i mnemonici AH, AL - BH, BL, - ecc … AX AH AL 12 La CPU Intel pentium 13 L’Unità di Controllo (CU) CU = Control Unit la CU è un dispositivo in grado di generare segnali sia per i circuiti esterni alla CPU (ad esempio segnali di lettura/scrittura per le memorie) che per i circuiti interni (ad esempio per l’ALU). La CU esamina il codice operativo dell’istruzione da eseguire e decide quali sono i vari passi che consentono l’esecuzione dell’istruzione stessa. In altre parole, la CU interpreta un’istruzione del programma per volta e comanda l’esecuzione dell’istruzione inviando alle altre unità appropriati segnali di controllo. 14 Unità Aritmetico-Logica (ALU) ALU = Arithmetical-Logical Unit Questa unità riceve in ingresso tipicamente due operandi e, a seconda del tipo di segnale proveniente dall’unità di controllo, esegue una operazione aritmetica (somma, sottrazione, ...) oppure un’operazione logica (and, or, not, …). L’ALU lavora generalmente con l’accumulatore ed un altro registro general pourpose. I risultati, parziali e non, vengono posti nell’accumulatore e, al termine dell’operazione, viene aggiornato, in modo opportuno, il registro di stato in base al risultato stesso. 15 L’esecuzione di un programma Fase di fetch, in cui la CU preleva dalla memoria l’istruzione che deve essere eseguita, il cui indirizzo è contenuto nell’Instruction Pointer (IP), la pone nell’Instruction Register (IR) ed incrementa il valore di IP per prepararsi poi ad eseguire l’istruzione successiva; Fase di decode (decodifica), in cui la CU interpreta il codice operativo dell’istruzione da eseguire contenuta in IR (in pratica determina cosa c’è da fare…) Fase di execute (esecuzione), in cui la CU genera i segnali di controllo necessari per l’esecuzione dell’istruzione: trasferimenti tra registri e/o memoria (ad esempio vengono letti altri dati dalla memoria e posti nei registri); operazioni che coinvolgono l’ALU, cioè invio di segnali opportuni all’ALU in grado di attivare una particolare operazione aritmetica o logica; operazioni di ingresso/uscita; modifica del contenuto di IP nel caso di istruzioni di salto. 16 L’esecuzione di un programma La CU esegue in continuazione il ciclo dell’istruzione (ovvero le fasi di fetch, decode ed execute)… … finché non si raggiunge l’ultima istruzione del programma. 17