A2 - IL PROCESSORE 8086 PDF

Summary

These notes describe the 8086 processor, including its architecture, registers, and memory organization. They include examples to illustrate the concepts.

Full Transcript

A2 - IL PROCESSORE 8086 Sistemi e reti - Classe III IIS G. Vallauri LA FAMIGLIA X86 È composta da numerosi processori, prodotti da Intel e altri (IBM, Fujitsu, OKI, Siemens,..) Il processore 8086 fu il primo della famiglia x86 All’interno di tale famiglia è garantita la co...

A2 - IL PROCESSORE 8086 Sistemi e reti - Classe III IIS G. Vallauri LA FAMIGLIA X86 È composta da numerosi processori, prodotti da Intel e altri (IBM, Fujitsu, OKI, Siemens,..) Il processore 8086 fu il primo della famiglia x86 All’interno di tale famiglia è garantita la compatibilità software «all’indietro» (retrocompatibilità all’indietro). Questo significa che ciascun processore può eseguire il codice prodotto per i processori precedenti. ARCHITETTURA X86 La compatibilità del software implica che i sistemi x86 condividono la stessa architettura logica, ossia la visione che del processore ha il programmatore (anche detta Instruction Set Architecture). L'architettura x86 può essere talvolta suddivisa in 3 tipologie x86-16: architettura a 16 bit (propria dell'8086) x86-32: architettura a 32 bit x86-64: architettura a 64 bit IL PROCESSORE 8086 Nato nel 1978. “Antenato” di tutti i processori della famiglia x86. Ha uno spazio di indirizzamento, cioè la dimensione massima della memoria centrale che può essere gestita all’interno del calcolatore, pari a 1 MB. Ha un parallelismo di 16 bit, cioè usa registri e bus su 16 bit I REGISTRI DEL 8086 ARCHITETTURA TIPI REGISTRI Registri dato Registri segmento Registri puntatore Registri di stato Registro MDR Registro MAR Registro IR REGISTRI DATO Sono: AX (Accumulator Register) BX (Base Register) CX (Count Register) DX (Data Register) Sono utilizzati per memorizzare operandi e risultato delle operazioni. Possono essere utilizzati come registri da 16 bit oppure come coppie di registri da 8 bit. ORGANIZZAZIONE MEMORIA La memoria è organizzata in segmenti, ognuno di dimensione pari a 64 Kbyte che possono essere di 4 tipologie: di codice, di dato, di stack o extra. REGISTRI SEGMENTO I registri sono: CS (Code Segment) DS (Data Segment) ES (Extra Segment) SS (Stack Segment) Vengono utilizzati per costruire gli indirizzi fisici con i quali fare accesso in memoria. Contengono i puntatori all'inizio dei segmenti di codice, di dato, extra e di stack, rispettivamente. REGISTRI PUNTATORE Contengono degli indirizzi RELATIVI (offset). I principali sono: PC (Program Counter) o IP: contiene l’indirizzo relativo (offset) della prossima istruzione da eseguire rispetto all’inizio del Code Segment (CS) SP (Stack Pointer): contiene l’indirizzo relativo della cella corrente dello stack rispetto all’inizio del Segmento di Stack (SS) SI, DI (Data Index): contengono l’indirizzo relativo del prossimo dato da prelevare rispetto al per i Data Segment (DS) REGISTRI PUNTATORE E SEGMENTO ALTRI REGISTRI IR (Istruction Register): all’interno viene memorizzato il codice binario dell’istruzione che deve essere eseguita dalla CPU (in esecuzione) MDR (Memory Data Register): all’interno vengono memorizzati i dati letti dal bus dati o che devono essere inviati al bus dati MAR (Memory Address Register): all’interno viene memorizzato l’ultimo indirizzo di memoria a cui la CPU ha fatto riferimento. Si tratta dell’unico registro a 20 bit REGISTRO DI STATO (PSW) Composto da 16 bit, ma solo 9 di questi vengono usati. Ogni bit corrisponde ad un flag (0 o 1) I flag si dividono in: flag di condizione flag di controllo PSW (FLAG DI CONDIZIONE) Vengono automaticamente scritti al termine di varie operazioni: SF (Sign Flag): coincide con il MSB del risultato dopo un’istruzione aritmetica ZF (Zero Flag): vale 1 se il risultato è nullo, 0 altrimenti PF (Parity Flag): Bit di parità. Vale 1 se il risultato contiene un numero pari di 1 CF (Carry Flag): Utilizzato nell’algebra dei numeri senza segno. Diventa 1 nel momento in cui una somma produce un riporto. Nel caso della differenza (somma in CA2), CF diventa 1 se per eseguire la sottrazione occorre un prestito, cioè se il risultato della somma è negativo OF (Overflow Flag): vale 1 se l'ultima istruzione ha prodotto un overflow PSW - FLAG DI CONTROLLO Possono venire scritti e manipolati da apposite istruzioni, e servono a regolare il funzionamento di talune funzioni del processore. I più importanti sono: IF (Interrupt Flag): abilita la gestione delle interruzioni mascherabili TF (Trap Flag): abilita la generazione di una interruzione alla fine di ogni istruzione (modalità debugger) COMPONENTI 8086 SISTEMA 8086 I BUS I bus, sono dei componenti che permettono la comunicazione fra la CPU, la Memoria Centrale e le varie Periferiche. I BUS sono suddivisi in: Address Bus: utilizzato dalla CPU per indirizzare la memoria centrale. Unidirezionale, di dimensioni pari a 20 bit nell’8086 Data Bus: trasportano i dati dalla CPU verso la Memoria Centrale e le altre periferiche. È condiviso fra tutti i moduli dell’elaboratore. Bidirezionale. La sua dimensione è pari a 16 bit (nell’8086). Control Bus: serve a controllare l’hardware esterno alla CPU, indicando il tipo di operazione che il sistema deve eseguire. Stabilisce tra le altre cose, chi in un determinato momento può leggere/scrivere sul Data Bus COMPONENTI PRINCIPALI EU (Execut ion Unit) it) l Un ntro (Co CU BIU (Bus Interface Unit) EXECUTION UNIT Si occupa di eseguire le istruzioni, decodificate dalla CU. L’elemento principale contenuto nella EU, è la ALU (Arithmetic Logic Unit), componente basato sulla logica combinatoria che svolge le operazioni logico-matematiche. Esso ammette al massimo due operandi alla volta. BUS INTERFACE UNIT Si occupa dell’interfacciamento ai bus. Tra le altre cose, contiene un sommatore (simile alla ALU), che permette di determinare dati i registri segmento e puntatore l’indirizzo assoluto su 20 bit di una qualsiasi locazione di memoria a cui si deve accedere CONTROL UNIT Permette l’esecuzione di una singola istruzione: ordina alla BIU di caricare la prossima istruzione, la decodifica e chiede alla EU di eseguirla. Le seguenti operazione sono iterate fino al termine del programma in esecuzione. Gestisce la sincronizzazione delle attività di tutti i dispositivi esterni, grazie tra le altre cose al clock, un segnale periodico. SCHEMA 8086 IL CLOCK L’attività della CPU è regolata mediante un clock esterno generato mediante un oscillatore ad elevata precisione. In corrispondenza di ogni colpo di clock la CPU esegue una certa operazione. la sua unità di misura è l’Herz. I sistemi 8086 utilizzavano un clock pari a 4,77 MHz, cioè erano già in grado di eseguire 4,77 milioni di operazioni al secondo. ESEMPIO 1 ESEMPIO 1 Soluzione N istruzioni: 2,5 * 10^9 f = N istruzioni al sec = 2,5*10^9 Hz = 2,5 GHz ESEMPIO 2 ESEMPIO 2 Soluzione Processore RISC esegue una istruzione ogni colpo di clock f = 5 KHz = 5*10^3 Hz --> N istruzioni = 5*10^3 istruzioni = 5000 istruzioni T = 1/f = 1/5000 Hz = 0.2 * 10^-3 s = 0.2 ms = 200 μs CICLO FETCH-DECODE-EXECUTE CICLO FDE (CICLO MACCHINA) Quando si avvia un qualsiasi programma, esso viene eseguito istruzione per istruzione dal processore. L’esecuzione di ciascuna istruzione si compone di 3 fasi: Fetch: la singola istruzione da eseguire viene letta dalla memoria e portata all’interno della CPU. Questo compito spetta alla BIU Decode: l’istruzione viene decodificata. Questo compito spetta alla CU Execute: l’istruzione viene eseguita, normalmente accedendo ad uno o più operandi, eseguendo l’operazione su di essi e scrivendo il risultato in memoria, se necessario. Questo compito spetta alla EU Dopo di che si passa a caricare l’istruzione successiva, rieseguendo il ciclo di F-D-E, e cosi via fino al termine del programma FASE DI FETCH 1. La CU trasferisce nel registro MAR l’indirizzo della istruzione da caricare. 2. Il contenuto di MAR, calcolato dalla BIU, viene caricato sul bus degli indirizzi, e contemporaneamente viene abilitato un segnale di Read (lettura) sul bus di controllo 3. La memoria decodifica l’indirizzo dell’istruzione da caricare, e la trasferisce sul Data Bus 4. L’istruzione viene portata dal Data Bus su MDR 5. L’istruzione viene copiata da MDR a IR 6. Il registro PC viene incrementato di una quantità pari alle dimensioni dell’istruzione caricata, così puntando alla prossima istruzione da eseguire FASE DI DECODE 1. La CU decodifica l’istruzione verificando quali registri sono coinvolti 2. OPZIONALMENTE, La CU legge un eventuale dato aggiuntivo dalla memoria centrale, eseguendo un secondo ciclo di fetch e provvedendo ad incrementare ulteriormente il registro PC. FASE DI EXECUTE 1. Carica i dati necessari sui registri di ingresso della ALU 2. CU genera i segnali di controllo (es. quale operazione deve eseguire) verso la ALU per eseguire l’istruzione 3. Preleva il risultato dal registro di output della ALU e lo carica nel registro di destinazione o eventualmente nel MDR se il risultato deve essere salvato in memoria 4. Se il risultato deve essere salvato in memoria, esegue un ultimo ciclo di scrittura in memoria. Terminata l’istruzione in corso, la CU riprende il ciclo caricando la prossima istruzione, fino al termine del programma. CICLO FDE GESTIONE MEMORIA 8086 SEGMENTI La memoria dell’8086 è organizzata in segmenti, aree di memoria ognuna della dimensione massima di 64 Kbyte. Tutti i segmenti cominciano ad indirizzi multipli di 16 CARATTERISTICHE SEGMENTI Ogni programma eseguito dall’8086 è suddiviso nella memoria in segmenti CODICE, DATI (o extra) e STACK Ogni programma può contenere PIU’ segmenti di codice o di dato, ma UNO solo di stack Ogni segmento ha una dimensione variabile, ma massima di 64 Kbytes e inizia sempre a una cella di posizione multipla di 16 (se l’indirizzo termina con ultimi 4 bit a 0) Il numero di segmenti massimo non è fisso, ma dipenderà dalla dimensione dei segmenti stessi SEGMENTO CODICE All’interno del segmento codice sono contenute tutte le istruzioni del programma in formato binario. Ogni istruzione, ha una sua dimensione variabile tra 1 e 6 bytes. I registri segmento e puntatore che gestiscono l’indirizzamento in memoria sono rispettivamente CS e PC (o IP) SEGMENTO DATI All’interno del segmento dati sono contenuti le variabili globali del programma. I registri segmento e puntatore che gestiscono l’indirizzamento in memoria sono rispettivamente DS e DI (o SI) *NB: Poiché 64 Kbytes potevano non bastare per contenere tutti i dati di un programma, venne introdotto un ulteriore segmento dati chiamato Extra Data Segment. Il registro segmento che gestisce l’indirizzamento in memoria è ES (Extra Segment) SEGMENTO STACK Nel segmento Stack vengono salvate le variabili locali e i parametri passati da un sottoprogramma. I registri segmento e puntatore che gestiscono l’indirizzamento in memoria sono rispettivamente SS e SP SPAZIO INDIRIZZAMENTO Lo spazio di indirizzamento è lo spazio di memoria messo a disposizione dal calcolatore per poter immagazzinare i programmi in esecuzione, che dipende dal numero N di bit a disposizione per ogni indirizzo di memoria. Nel 8086 avendo 20 bit a disposizione, il suo spazio di indirizzamento è pari a 1 MB. CALCOLO INDIRIZZI Ogni volta che l'8086 deve generare un indirizzo assoluto su 20 bit, esso esegue un’operazione di somma tra il contenuto di un registro segmento, detto INDIRIZZO RELATIVO ed il contenuto di un registro puntatore, detto OFFSET. La somma avviene dopo aver moltiplicato per 16 (shift di 4 posizioni in avanti) il contenuto del registro di segmento ESEMPIO 1 Si consideri un programma scritto in linguaggio Assembler e in esecuzione, caricato all’interno della Memoria Centrale. Sono stati creati tre segmenti in memoria, tra cui il segmento codice che ha inizio all’indirizzo 14B10h. Sapendo che si deve eseguire l’istruzione che ha offset rispetto all’inizio del segmento codice pari a 1234h, determinare: Il contenuto del registro CS Il contenuto del registro PC Il valore dell’indirizzo assoluto dell’istruzione a cui si sta facendo riferimento, in base al contenuto dei registri ESEMPIO 1 Soluzione 1) CS: 14B1h 2) PC: 1234h 3) Indirizzo Assoluto: 14B10h + 01234h = 15D44h ESEMPIO 2 Si consideri un programma scritto in linguaggio Assembler e in esecuzione, caricato all’interno della Memoria Centrale. Sono stati caricati i vari segmenti in memoria, tra cui il segmento codice che ha inizio all’indirizzo 00100h e il segmento dati che ha inizio all’indirizzo 65840h. Il registro PC punta all’inizio del Segmento Codice. Sapendo che si deve accedere ad un dato in memoria che ha offset rispetto all’inizio del Segmento Dati pari a AB00h, determinare: Il contenuto dei registro CS e PC, DS e DI Il valore dell’indirizzo assoluto del dato a cui si deve far accesso in memoria, in base al contenuto dei registri opportuni ESEMPIO 2 Soluzione 1) CS: 0010h, PC: 0000h - DS:6584h, DI: AB00h 2) Indirizzo Assoluto DS*16+DI : 65840h +0AB00h = 70340h ESEMPIO 3 Si consideri un programma scritto in linguaggio Assembler e in esecuzione, caricato all’interno della Memoria Centrale. Sono stati caricati i vari segmenti in memoria; il registro CS contiene al suo interno il valore 1011h e il PC ha un offset di 70 byte rispetto all’inizio del segmento codice. Sapendo che si deve eseguire l’istruzione puntata dai registri precedentemente descritti, determinare: Il valore dell’ indirizzo assoluto dell’inizio del segmento codice Il valore del registro PC Il valore dell’indirizzo assoluto dell’istruzione a cui si sta facendo riferimento in memoria ESEMPIO 3 Soluzione 1) Indirizzo inizio segmento codice : 10110h 2) PC = 0046h 3) Indirizzo Assoluto istruzione CS*16+PC : 10110h +00046h = 10156h GESTIONE STACK SEGMENTO STACK Nel segmento Stack vengono salvate le variabili locali e i parametri passati da un sottoprogramma. I registri segmento e puntatore che gestiscono l’indirizzamento in memoria sono rispettivamente SS e SP SEGMENTO STACK A differenza dei segmenti precedenti, nello stack il programma non può andare a scrivere direttamente, ma può scrivere soltanto seguendo la regola LIFO (Last In First Out), cioè impilando i dati uno sopra l’altro. Il segmento di stack viene gestito in maneira differete rispetto agli altri segmenti: tipicamente ha una dimensione fissa di 1024 bytes, ma comunque impostabile via codice dal programma utente lo Stack Pointer (SP), anziché puntare alla cella iniziale (con offset 0000), punta all’ultima cella in fondo, contenente il valore speciale EOS (End Of Stack). OPERAZIONI PUSH - POP Le due istruzioni usate per gestire lo stack sono le istruzioni: PUSH: consente di salvare una informazione nello Stack POP: consente di prelevare dallo Stack l’ultima informazione memorizzata Ad ogni PUSH: SP viene decrementato di una quantità pari alle dimensioni dell’informazione salvata. Se si continuano ad inserire dati ed SP viene decrementato fino ad arrivare a 0 si ottiene un errore di stack overflow che significa che lo Stack è arrivato oltre il massimo della capienza. Ad Ogni POP: SP viene incrementato di una quantità pari alle dimensioni dell’informazione. Se si continuano ad inserire dati ed SP viene incrementato fino ad arrivare alla sua dimensione massima si ottiene un errore di stack underflow che significa che lo Stack è vuoto. PUSH E POP PUSH E POP AX = 2 Stato iniziale PUSH 2 POP AX ESEMPIO 1 Si consideri un segmento stack che inizia all’indirizzo di memoria 10010h, PUSH 12 inizialmente vuoto, di dimensione fissa 20 bytes. POP AX Considerando ogni valore su 2 byte, un programma Assembler esegue le operazioni mostrate nel segmento codice scritto a fianco. PUSH 4 PUSH 15 Determinare: POP AX 1) Il contenuto del registro SS e SP, prima dell’esecuzione delle operazioni sullo stack PUSH 16 2) Il contenuto finale dello stack 3) Il valore del registro SP e l’indirizzo di memoria dove si trova il top dello stack, al il termine delle operazioni eseguite al punto precedente; controllando se non viene eseguito nessun underflow/overflow ESEMPIO 1 Soluzione 1) SS = 1001h SP = 0014h 3) SP = 0010h (due valori inseriti nello stack al termine) indirizzo: SS*16+SP = 10010+0010=10020h ESEMPIO 2 PUSH 23 Si consideri un segmento stack che inizia all’indirizzo di memoria 1AB00h, inizialmente vuoto, di dimensione fissa 30 bytes. PUSH 5 Considerando ogni valore su 2 byte, Un programma Assembler esegue le operazioni PUSH 4 mostrate nel segmento codice scritto a fianco. POP AX Determinare: POP BX 1) Il contenuto del registro SS e SP, prima dell’esecuzione delle operazioni sullo stack POP CX 2) Il contenuto finale dello stack e dei registri dato POP DX 3) Il valore del registro SP e l’indirizzo di memoria dove si trova il top dello stack, al il termine delle operazioni eseguite al punto precedente; controllando se non viene PUSH 4 eseguito nessun underflow/overflow ESEMPIO 3 PUSH 20 Si consideri un segmento stack con SS che contiene il valore 1CA1h, inizialmente PUSH 15 vuoto, di dimensione fissa 4 bytes. POP AX Considerando ogni valore su 1 byte, un programma Assembler esegue le seguenti operazioni nel segmento codice scritto a fianco. PUSH 15 POP BX Determinare: POP CX 1) Il contenuto del registro SS e SP, prima dell’esecuzione delle operazioni sullo stack 2) Il contenuto finale dello stack e dei registri dato PUSH 15 3) Il valore del registro SP e l’indirizzo di memoria dove si trova il top dello stack, al il PUSH 3 termine delle operazioni eseguite al punto precedente; controllando se non viene PUSH 1 eseguito nessun underflow/overflow PUSH 10 LA PIPELINE CICLO F-D-E SENZA PIPELINE L’esecuzione sequenziale delle fasi di Fetch – Decode – Execute spreca tantissimo tempo. Durante la fase di FETCH mentre la BIU provvede a caricare l’istruzione utilizzando i bus di sistema di collegamento fra CPU e memoria, la EU rimane praticamente inutilizzata. Viceversa, durante la fase di EXECUTE dell’istruzione da parte della EU, rimangono inutilizzati i BUS (e quindi la BIU). CICLO F-D-E CON PIPELINE Proprio per evitare questi tempi di inutilizzo e velocizzare le operazioni, la CPU è stata suddivisa in parti: la EU, la CU e la BIU. La pipeline, cioè «catena di montaggio», permette una elaborazione parallela: mentre la EU esegue l’istruzione corrente ,la BIU provvede a scaricare l’istruzione successiva, e la CU coordina tutte le operazioni. La BIU si occupa, durante la fase di fetch, di caricare l’istruzione in una piccola coda, una memoria che segue una politica FIFO (First In First Out) detta INSTRUCTION QUEUE (o coda di prefetch), della dimensioni di 6 bytes, tanto quanto la dimensione massima di una istruzione Assembly. CICLO F-D-E CON PIPELINE Grazie a questa coda, al termine dell’esecuzione dell’istruzione corrente, la CU trova l’istruzione successiva già pronta all’interno della coda di prefetch. Provvede quindi a trasferirla alla EU, ad incrementare PC e a segnalare alla BIU di caricare la prossima istruzione, e, in base al nuovo valore di PC, la BIU elimina dalla coda l’istruzione “consumata”, fa avanzare la successiva istruzione in testa alla coda di prefetch e provvede ad un nuovo caricamento. CICLO F-D-E SENZA PIPELINE vs CON PIPELINE

Use Quizgecko on...
Browser
Browser