Personal computer: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Pizeta (discussione | contributi)
Pizeta (discussione | contributi)
Riga 1 037:
 
=== Numero di clock necessari per eseguire le istruzioni ===
 
Il numero di cicli di clock per eseguire una qualsiasi istruzione del DLX si ottiene contando gli stati del controller per ogni istruzione, il valore reale dipende poi dal numero e dalla durata degli accessi alla memoria, la seguente tabella riassume il numero di cicli di clock e il numero degli accessi alla memoria per le istruzioni del DLX nel caso in cui l'accesso alla memoria duri '''1''' clock
 
 
{| cellpadding='8'
!'''Istruzione'''
!'''Numero minimo
di clock'''
!'''Accessi alla
memoria'''
|-
|Caricamento
|<center> 6 </center>
|<center> 2 </center>
|-
|Memorizzazione
|<center> 5 </center>
|<center> 2 </center>
|-
| ALU
|<center> 5 </center>
|<center> 1 </center>
|-
| Inizializzazione
|<center> 6 </center>
|<center> 1 </center>
|-
| Jump
|<center> 3 </center>
|<center> 1 </center>
|-
| Jump and link
|<center> 5 </center>
|<center> 1 </center>
|-
| Branch taken
(eseguito)
|<center> 4 </center>
|<center> 1 </center>
|-
| Branch not taken
|<center> 3 </center>
|<center> 1 </center>
|}
Qualora l'accesso alla memoria duri più cicli di clock, questi andrebbero moltiplicati al numero di accessi alla memoria e sommati al numero minimo di cicli di clock, in questo caso si parla di ''cicli di stallo della memoria'' o ''stati di attesa'' o '''wait'''. In macchine dotate di cache i cicli di wait valgono zero ( l'accesso alla memoria cache richiede quindi un solo clock )
 
==== Calcolo del CPI ====
Line 1 087 ⟶ 1 042:
Supponiamo di avere un programma che esegue le seguenti operazioni con frequenza relativa:
 
Caricamento 21 %
Memorizzazione 12 %
 
ALU 37 %
Memorizzazione 12 %
Inizializzazione 6 %
 
ALU Jump 37 2 %
Jump an link 0 %
 
Branch taken 12 %
Inizializzazione 6 %
Branch not taken 11 %
 
Jump 2 %
 
Jump an link 0 %
 
Branch taken 12 %
 
Branch not taken 11 %
 
Il CPI medio, ricordando la formula data nel primo capitolo, si ottiene sommando i prodotti tra il CPI di ogni istruzione (secondo la tabella sopra riportata e gli stati di wait) e la sua frequenza relativa,
in questo esempio il CPI medio risulta '''6,28'''
 
= 8086 =
 
L'Intel 8086 nasce come un'estensione del 8080, una macchina ad accumulatore. E' quindi sostanzialmente un ibrido, perché pur avendo 14 registri, nessuno di questi è ad uso generale in quanto ognuno ha un uso ben specifico.
 
L'architettura è a 16 bit così come i registri, ma per ottenere un'indirizzabilità maggiore i progettisti hanno aggiunto dei ''segmenti'' che estendono lo spazio di indirizzamento a 20 bit.
 
Fanno parte della stessa famiglia, sono quindi molto simili, i processori 80186, 80286 (indirizzamento a 24 bit), 80386 (indirizzamento e parallelismo a 32 bit), 80486 (poche novità rispetto all'80386 ma con prestazioni notevolmente migliorate).
 
 
== Registri e indirizzamento ==
 
Un indirizzo a 20 bit si ottiene da un indirizzo effettivo a 16 bit (''offset'', registro di indirizzo) sommandogli un indirizzo base a 20 bit, con lo scorrimento verso sinistra di quattro posizioni del contenuto di un registro segmento a 16 bit.
 
 
I 14 registri dell'8086 sono raggruppabili in 4 categorie: Dato, Indirizzo, Segmento e Controllo.
 
* '''Dato''': Usati per mantenere dati o per operare su di essi:
** '''AX''' Usato per moltiplicazioni, divisioni, I/O o operando implicito.
** '''BX''' Può essere un registro per contenere l'indirizzo base.
** '''CX''' Usato per le operazioni tra stringhe o istruzioni di ciclo.
** '''DX''' Usato per moltiplicazioni, divisioni e I/O.
* '''Indirizzo''': Usati per formare un indirizzo effettivo di memoria a 16 bit (interno al segmento):
** '''SP''' Puntatore alla sommità dello stack.
** '''BP''' Registro base: usato nell'indirizzamento tramite base.
** '''SI''' Registro indice: usato anche come base per l'indirizzo di una stringa.
** '''DI''' Registro indice: usato anche come base per l'indirizzo di destinazione di una stringa.
* '''Segmento''': Usati per costruire indirizzi di memoria a 20 bit:
** '''CS''' Segmento di codice: è usato per gli accessi alle istruzioni.
** '''SS''' Segmento dello stack: è usato per i riferimenti allo stack.
** '''ES''' Segmento aggiuntivo: usato per le operazioni destinate a una stringa.
** '''DS''' Segmento dati: usato per tutti gli altri casi.
* '''Controllo''': Usati per il controllo dello stato e del programma:
** '''IP''' Instruction Pointer: fornisce l'offset dell'istruzione corrente in esecuzione (16 bit meno significativi del PC).
** '''FLAGS''' Contiene 6 bit relativi alle condizioni (riporto, zero, segno, prestito, parità e overflow) e 3 bit per il controllo dello stato.
 
 
Le istruzioni ALU sono di tipo Memory-Register (2,1) e consentono l'uso di un operando immediato.
 
Le modalità di indirizzamento sono
* ''Registro indiretto'': BX, SI, DI.
* ''Base + offset a 8 o 16 bit'': BP, BX, SI, DI.
* ''Indicizzato'': l'indirizzo è la somma di due registri BP+SI, BP+DI, BX+SI, BX+DI.
* ''Indicizzato + offset a 8 o 16 bit'': l'indirizzo è la somma dell'offset con il contenuto di due registri.
 
== Operazioni ==
 
Possono essere suddivise in quattro categorie:
 
* Trasferimento dati, comprendono spostamenti (''move''), inserimento (''push'') ed estrazione (''pop'') di dati dallo stack.
* Istruzioni ALU
* Istruzioni di controllo del flusso, comprendono le diramazioni con e senza condizione, le chiamate e i ritorni dalle chiamate (l'utilizzo dello stack piuttosto che un registro come nel DLX permette il nesting-annidamento delle chiamate a procedura)
* Istruzioni su stringhe, come spostamento e confronto.
 
Alcune delle istruzioni tipiche sono:
* Trasferimento dati
** '''MOV''' Sposta un dato tra due registri o tra un registro e la memoria
** '''PUSH''' Metti un operando nello stack
** '''POP''' Leggi un operando dallo stack e mettilo in un registro
** '''LES''' Carica ES e uno dei GPR dalla memoria
* Istruzioni ALU
** '''ADD''' Addizione tra operando sorgente e operando destinazione
** '''SUB''' Sottrazione dell'operando sorgente da quello di destinazione
** '''CMP''' Confronto tra operando sorgente e destinazione
** '''SHL''','''SHR''' Scorrimento logico rispettivamente a sinistra e a destra
** '''RCR''' Rotazione a destra attraverso il riporto
** '''CBW''' Conversione di un byte in AL in una parola AX
** '''TEST''' And logico tra le configurazione dei flag sorgente e distinazione
** '''INC''','''DEC''' Incremento o decremento dell'operando destinazione
** '''OR''' OR logico
** '''XOR''' OR esclusivo
* Controllo
** '''JNZ''','''JZ''' Salta se è verificata la condizione IP + 8 bit di offset (in alternativa anche JN e JE)
** '''JMP''','''JMPF''' Salto non condizionato
** '''CALL''','''CALLF''' Chiamata a subroutine, l'indirizzo di ritorno è inserito nello stack
** '''RET''','''RETF''' Leggi dallo stack l'indirizzo di ritorno e salta ad esso
** '''LOOP''' Diramazione di ciclio: decrementa CS, se diverso da zero salta a IP + 8 bit di offset.
* Istruzioni su stringhe
** '''MOVS''' Copia la stringa sorgente in quella destinazione
** '''LODS''' Carica un byte o una parola di stringa nel registro A.
Per le istruzioni di stringa esiste un prefisso di ripetizione, questo significa che l'operazione deve essere ripetuta tante volte quanto indicato dal valore nel registro CX.
 
Le istruzioni di controllo di flusso devono essere in gradi di gestire sia trasferimenti ''vicini'' (all'interno del segmento di memoria indirizzabile con i 16 bit del registro) sia trasferimenti ''lontani'' (suffisso F, segmenti che richiedono indirizzi a 20 bit). Nei salti lontani all'OpCode seguono due quantità da 16 bit, una di queste è il puntatore all'istruzione, l'altra è caricata in CS e diventa il nuovo codice di segmento. Un ritorno lontano legge dalla cima dello stack sia il puntatore all'istruzione, sia il codice di segmento.
 
La codifica delle istruzione dell'8086 è piuttosto complessa e presenta diversi formati che possono variare a da uno a sei byte. Inoltre molte delle istruzioni contengono un campo da un bit w che specifica se l'operazione è di un byte o di una parola (2 byte).
Alcune istruzioni contengono insieme con l'OpCode la modalità di indirizzamento e il registro, altre istruzioni ancora usano un byte aggiuntivo, il ''postbyte'', con le informazioni sulla modalità di indirizzamento (è usato spesso per le istruzioni che indirizzano la memoria)
 
 
==Appendici==
 
=== Le velocità di ogni tipo di connessione interna ed esterna al personal computer ===
 
 
=== Riassunto ===
====Componenti notevoli====
 
=====EPROM=====
[[Immagine:eprom.png|170px|right]]Una Eprom è un dispositivo di memoria statica che deriva il suo nome dalle sue caratteristiche principali: Eraseable Progammable Read Only Memory. Ovvero Cancellabile, programmabile, leggibile. La programmazione di una EPROM avveniva infatti una sola volta, e comunque non era così facile aggiornare il programma contenuto in una EPROM, poiché la cancellazione avveniva solo tramite l'uso di una luce a raggi ultravioletti. Oggi le cose sono molto diverse. Non esistono più solo EPROM ma anche EEPROM ovvero Electrically Eraseable PROM, che sarebbero EPROM che possono essere cancellate e riprogrammate atraverso impulsi elettrici inviati ad alcune porte del chip.
 
Caratteristiche delle EPROM:
* La capacità va a potenze di 2: 32k, 64k, 128k, 256k, ...
* Le sigle sono del tipo 27xxx, con xxx indicante le dimensioni in Kbits
 
Porte del chip:
 
* GND - porta a massa
* VCC - porta da connettere all'alimentazione
* A0 .. A16 - porte degli ingressi
* D0 .. D7 - porte delle uscite
* CE* - Chip Enable, porta che permette di accendere il chip solo quando serve.
* OE* - Output Enable, porta che permette ai dati di essere letti
* PGM* - Porta che consente ad un programmatore di inserire i dati nella EPROM. Spenta questa porta tutte le altre diventano porte programmabili.
 
=====Ram=====
[[Immagine:ram.png|170px|right]]La Ram, Random Access Memory, è il dispositivo di memoria rapida del calcolatore. Al contrario della EPROM deve essere sia leggibile che, soprattutto, scrivibile in tempi molto ristretti. Esistono due tipi di RAM costruiti in modo completamente diverso. La SRAM, ovvero Static RAM, è composta da Flip-Flop che mantengono memorizzati i dati. Il tempo di accesso è minimo, ma la capacità è minore rispetto alle DRAM. Queste, Dynamic RAM, sono composte da transistor di tipo MOS. La capacità aumenta, ma la velocità di accesso è minore.
 
[[Immagine:ram logic.png|thumb|left]]La struttura logica interna di una RAM è comunque comune ad entrambi i tipi di RAM. L'aspetto fondamentale è nel doppio uso del bus di dati che in caso di scrittura porta il dato da scrivere, mentre in caso di lettura porta il dato letto. Questo attraverso un intelligente uso di un buffer tri-state.
 
Caratteristiche della RAM
* Capacità a potenze pari di 2
* Sigla: 62xxx
 
Porte del chip:
* GND - a massa
* VCC - Tensione di alimentazione
* CE* - Chip Enable - accensione del chip di RAM
* OE* - Output Enable - va a zero nel momento della lettura
* WE* - Write Enable - va a zero nel momento della scrittura
* A0 .. A16 - Indicatori della posizione della casella di memoria
* I/O0 .. I/O7 - Dati in uscita o ingresso
 
=====74xx244=====
[[Immagine:74xx244.png|100px|right]]Questo Circuito integrato consiste in un insieme di 2 gruppi di three-state buffer da quattro bit ciascuno. Ogni gruppo è comandato indipendentemente dall'altro.
 
Porte dell'integrato:
* ENx* - abilita il gruppo ''x'' di three-state buffer
* xA1 .. xA4 - Bit in ingresso da abilitare o portare a stato di alta impedenza
* xY1 .. xY4 - output del buffer three-state
 
=====74xx245=====
[[Immagine:74xx245.png|100px|left]]Un integrato come il precedente è utile, ma spesso può essere necessario abilitare alternativamente sullo stesso canale sia ingresso che uscita. Per minimizzare lo spazio necessario per un tal genere di esigenza esiste l'integrato 245. Questo si compone di una coppia di three-state buffer in direzioni opposte aperti alternativamente attraverso un comando DIR. Una struttura come questa è detta transceiver. La struttura logica è per il resto sostanzialmete identica alla precedente.
 
====DLX====
 
======Formato operazioni======
Ogni OpCode è composto di 6 bit, ogni indirizzo di 5, mentre i restanti bit sono eventualmente per offset o altri tipi di input. Le tre grandi famiglie di comandi sono:
 
[[Immagine:I-format.gif|right|Formato I]] Formato I: E' quello utilizzato per ogni operazione con operatori immediati. Come si nota l'offset è di soli 16 bit, il che significa che non si può passare come argomento direttamente un dato a 32 bit, bensì bisogna suddividerlo in due passaggi con in mezzo uno shift di 16 posizioni.
 
[[Immagine:R-format.gif|left| Formato R]] Formato R: Questo è il formato delle operazioni fra registri. Gli 11 bit finali vengono utilizzati per rendere più specifiche alcune operazioni (ricordiamo che essendoci solo 6 bit per le operazioni, il numero massimo di queste è <math>2^{6}=64</math>)
 
[[Immagine:J-format.gif|right| Formato J]] Formato J: Quest'ultimo è il formato dei salti condizionati o meno.
 
======Operazioni======
*Trasferimenti di dati
**'''LB, LBU, SB '''Load byte, load byte unsigned, store byte
**'''LH, LHU, SH''' Load halfword, load halfword unsigned, store halfword
**'''LW, SW''' Load word, store word (a/da registri integer)
**'''LF, LD, SF, SD''' Load SP float, load DP float, store SP float, store DP float (SP - single precision, DP - double precision)
**'''MOVI2S, MOVS2I''' Move from/to GPR to/from a special register
**'''MOVF, MOVD''' Copy one floating-point register or a DP pair to another register or pair
**'''MOVFP2I, MOVI2FP''' Move 32 bits from/to FP tegister to/from integer registers
 
*Aritmetica/Logica
**'''ADD, ADDI, ADDU, ADDUI''' Add, add immediate (tutti gli immediati sono a 16 bit); signed and unsigned
**'''SUB, SUBI, SUBU, SUBUI''' Subtract, subtract immediate; signed and unsigned
**'''MULT, MULTU, DIV, DIVU''' Multiply and divide, signed and unsigned; Gli operandi devono essere registri Floating-point; Tutte le operazioni richiedono valori a 32 bit e danno come risultato valori a 32 bit.
**'''AND, ANDI''' And, And immediate
**'''OR, ORI, XOP, XOPI''' Or, or immediate, exclusive or, exclusive or immediate
**'''LHI''' Load high immediate - carica nella parte alta del registro il dato immediato
**'''SLL, SRL, SRA, SLLI, SRLI, SRAI''' Shifts: sia mmediato(S__I) che variabile (S__); gli shift sono Shift Left Logical, Right Logical, Right Arithmetic
**'''S__, S__I''' Set condizionati: "__" può essere LT, GT, LE, GE, EQ, NE
 
*Controlli
**'''BEQZ, BNEZ''' Branch GPR equal/not equal to zero; 16-bit offset from PC
**'''BFPT, BFPF''' Test comparison bit in the FP status register and branch; 16-bit offset from PC
**'''J, JR''' Jumps: 26-bit offset from PC(J) or target in register(JR)
**'''JAL, JALR''' Jump and link: save PC+4 to R31, target is PC-relative(JAL) ot a register(JALR)
**'''TRAP''' Transfer to operating system at a vectored address
**'''RFE''' Return to user code From an Fxception; restore user code
 
*Floating point
**'''ADDD, ADDF''' Add DP, numeri SP
**'''SUBD, SUBF''' Subtract DP, numeri SP
**'''MULTD, MULTF''' Multiply DP, SP floating point
**'''DIVD, DIVF''' Divide DP, SP floating point
**'''CVTF2D, CVTF2I, CVTD2F''',
**'''CVTD2I, CVTI2F, CVTI2D''' Istruzioni di Conversione: CVTx2y converte dal tipo ''x'' al tipo ''y'', dove x e y sono I(Integer), D(Double precision), o F(Single precision). Entrambi gli operandi sono nel registro FP
**'''__D, __F''' confronti DP e SP: "__" può essere LT, GT, LE, GE, EQ, NE; impostare il bit di paragone nel registro FP.