sabato 4 settembre 2010

Print
Dopo una serie di articoli dedicati a periferiche strettamente collegate all'ambito videoludico (schede grafiche ed audio), a partire da questo post, vorrei affrontare con voi l'evoluzione dei processori, o CPU (Central Processing Unit) per utilizzare un acronimo che fa tanto ingegnere, cuori pulsanti dei nostri amati PC.
La nostra storia  non può che partire dal mitico Intel 8086, capostipite dalla famigerata architettura x86 che ancor oggi, sebbene evoluta e adeguatamente aggiornata, è alla base dei PC che utilizziamo quotidianamente con la stessa familiarità con cui adoperiamo una caffettiera per preparare un buon caffè.

Il chip Intel 8086 in tutto suo splendore (fa quasi tenerezza!!)

Un po' di storia

Nel 1972, Intel lancia l'8008 il primo microprocessore 8-bit della storia. Progettato per la realizzazione di video terminali, non ebbe un grande successo vista la scarsa adattabilità a contesti diversi da quelli per cui era stato pensato. Oltre a questo, visti i soli 18 piedini (pin) dispononibili per collegarlo al resto dell'hardware dell'elaboratore, necessitava di parecchia logica esterna per espletare le proprie funzioni (era di fatto un microprocessore "monco"). A due anni di distanza arriva l'8080, che grazie all'utilizzo di un più spazioso case
a 40 pin permette di inglobare tutta la logica necessaria al funzionamento diventando di fatto il primo microprocessore single-chip ad 8-bit. L'8080 fu alla base di storici computer quali l'Altair 8800 e l'IMSAI 8080, sistemi che a guardarli oggi sembrano tutto fuorché parenti degli "elettrodomestici" che sovrastano le nostre scrivanie.


 
Senza parole :o)


Il successo dell'8080 fu però incrinato dall'uscita nel 1986 dello Zilog Z80 (ad opera di un gruppo di transfughi di Intel), che divenne in breve il più popolare microprocessore ad 8-bit di tutti i tempi. Compatibile con l'8080 ma più performate vista la migliore realizzazione, lo Z80 è il microprocessore alla base di molti dei sistemi amati dei retrogramers quali lo ZX Spectrum, l'MSX-1, l'Amstrad CPC e il TSR-80. Tale fu il successo dello Z80 e del CP/M (sistema operativo ad esso legato) che il Commodore 128 integrava al suo interno tale processore. Nello stesso periodo escono anche lo sfortunato Motorola 6800 (1974) ed il mitico MOS 6502 (1975) processore scelto da Steve Wozniak per i suoi Apple I e Apple II entrambi superiori in prestazioni all'8080.
Nel 1977, Intel lancia l'8085 più economico e prestante del modello precedente ma non in grado di reggere il passo con la concorrenza. L'era degli 8-bit si chiude quindi con una sonora sconfitta per la casa Santa Clara (California).

L'8086 (anche noto come iAPX86) è il primo processore a 16-bit realizzato da Intel; il suo studio iniziò nel 1976 per concludersi con il lancio sul mercato nel 1978. Per dovere di cronaca cito il TMS-900, il primo microprocessore single-chip a 16-bit della storia, introdotto da Texas Instruments nel 1976 in seguito utilizzato nel celebre home computer TI-990/4A (celebre non tanto per le sue prestazioni o la sua diffusione ma quanto, per essere stato pubblicizzato dal grandissimo Bill "Signor Robinson" Cosby!!!).

Non c'entra nulla ma non potevo esimermi ... MITICO!!!!!!

Scusate la divagazione ma anche questa è cultura!!! Bene torniamo a nostro 8086 ... il processore fu progettato per essere compatibile a livello di codice sorgente con i sui predecessori (8085, 8080 e 8008), scelta che consentì di poter riutilizzare il software già scritto "semplicemente" ricompilandolo i programmi. Il modello di programmazione ed il set di istruzioni del processore è quindi quello dei modelli precedenti, arricchito delle funzionalità necessarie a sfruttare la nuova architettura a 16-bit. Per facilitare l'utilizzo di lunguaggi di programmazione di alto livello, come il Pascal ed il PL/M che si stavano rapidamente diffondendo, vennero inserite della apposite istruzioni che ne rendevano più efficiente l'esecuzione. Ulteriori innovazioni furono l'introduzione di microcodice, implemetazione in hardware di operazioni di alto livello, per le moltiplicazione e le divisioni ed una progettazione dei segnali di controllo della CPU pensati per gestire eventuali coprocessori e sistemi multiprocessore.
Nonostante queste interessanti caratteristiche, l'8086 fu un processore molto criticato per alcune discutibili scelte architetturali (non preoccupatevi, ne parleremo in seguito); con ogni probabilità non era neppure il migliore processore presente sul mercato. La sua fortuna fu quella di essere scelto da IBM come cuore della nascente architettura PC, scelta che portò l'architettura x86 ad imporsi a livello planeratario nonostante i sui iniziali difetti (discorso analogo si può fare per il sistema operativo l'MS-DOS). Come spesso accade, ad imporsi non è il prodotto migliore ma quello che viene venduto meglio.

Dettagli architetturali

Bus di indirizzamento e dati

L'8086 adotta un bus di 20 bit per l'indirizzamento che gli permette di accedere ad 1MB di memoria (2^20 = 1.048.576), un discreto passo in avanti rispetto ai soli 64KB utilizzabili dalle precedenti versioni dei processori Intel. Ad onor del vero di questi, solamente i primi 640KB (la memoria convenzionale, con cui si lottava quotidianamente per far partire i giochi) erano utilizzabili dalle applicazioni a causa della scelta degli ingegneri IBM di dedicare i restanti 384KB al BIOS ed al mapping delle periferiche (in seguito venne trovato il modo di sfruttare alcuni di questi 384KB tramite i famigerati gestori di memoria estesa).
Per contenere i costi del pressore, i tecnici Intel decisero di utilizzare per il packaging lo stesso case a 40 pin già utilizzati per l'8080 e l'8085. Questa scelta rendeva di fatto impossibile utilizzare altri 16 pin per il bus dati, in quanto sarebbero restati solamente 4 contatti per gestire i segnali di controllo (decisamente troppo pochi). Fu quindi necessario utilizzare il multiplexing per poter trasferire dati diversi sugli stessi pin (in un caso gli indirizzi e nell'altro i dati veri e propri). In pratica, i primi 16 pin del bus di indirizzamento sono utilizzanti per trasferire (in momenti diversi) anche dati. Benché lo scopo fosse nobile, tale scelta influì pesantemente sulle prestazioni del processore in quanto, per poter effettuare un operazioni di scrittura/lettura della memoria erano necessari due cicli di bus, uno per selezionare la locazione ed uno per far viaggiare i dati.  Usa scelta non drammatica ma comunque discutibile!

Pin layout dell'8086
Registri

I registri sono locazioni di memoria interne alla CPU accessibili con estrema velocità. La maggior parte computer si basa sull'architettura load-store (carica e memorizza) che prevede di: copiare i dati dalla memoria ai registri, eseguire le necessarie elaborazioni per poi copiare il risultato nuovamente in memoria.

L'8086 dispone di 14 registri a 16-bit, suddivisi in quattro gruppi funzionali:
  • registri d'uso generale utilizzati per compiere le elaborazioni vere e proprie (possono essere utilizzati anche come 8 registri a 8-bit)
    • AX: registro accumulatore utilizzato per le operazioni artimetico/logiche, per operazioni di input-output e per memorizzare parte dei risultati delle operazioni di moltiplicazioni e divisione
    • BX: registro base utilizzato come accumulatore o come puntatore alla memoria
    • CX: registro contatore utilizzato per i cicli
    • DX: registro dati utilizzato in combinazione con AX per memorizzare valori lunghi 2 word (32 bit) come ad esempio il risultato di una moltiplicazione tra due valori a 16 bit.
  • registri indice e segmento utilizzati per accedere alla memoria (maggiori dettagli nel paragrafo successivo)
  • registro di stato i cui diversi bit indicano il verificarsi di una data condizione
    • C: l'operazione ha generato un riporto
    • Z: il risultato dell'operazione è zero
    • S: il risultato è negativo
    • ...
A questi va aggiunto il registro che contiene l'indirizzo della prossima istruzione (Istruction Pointer o Program Counter). Il valore di tale registro viene incrementato automaticamente durante il normale ciclo di esecuzione di un programma in linguaggio macchina. Il suo valore può essere "manipolato" tramite le istruzioni di salto che permettono di controllare il flusso del programma (ad esempio per eseguire o meno un determinato blocco di codice al verificarsi di una condizione oppure richiamare una procedura)

Registri d'uso generale
AH AL AX (accumulatore)
BH BL BX (base)
CH CL CX (contatore)
DH DL DX (dati)
Registri indice
SI Source Index
DI Destination Index
BP Base Pointer
SP Stack Pointer
Registro di stato
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 (bit position)
- - - - O D I T S Z - A - P - C Flags
Registri di segmento
CS Code Segment
DS Data Segment
ES ExtraSegment
SS Stack Segment
Puntatore istruzione
IP Instruction Pointer

I registri dell'8086

Segmentazione

Andiamo adesso ad analizzare una della caratteristiche più bizzarre dell'8086: l'accesso alla memoria. Leggendo i paragrafi precedenti vi sarete accorti che tutti i registri dell'8086 sono in grado di memorizzare 16-bit mentre il bus di indirizzamento ha un'ampiezza di 20-bit. Anche senza essere dei guru dell'informatica, penso che a tutti sarà sorta la domanda: "dove saltano fuori i 4 bit che mancano?".
La scelta fu quella di introdurre i registri di segmento (CS, DS, ES, SS) da cui prelevare i 4 bit necessari a generare l'indirizzo fisico su 20 bit. Ad esempio, il registro CS (Code Segment) contiene l'indirizzo del segmento di codice utilizzato in combinazione con l'instruction pointer per determinare l'indirizzo della prossima istruzione mentre, il registro DS (Data Segment) permette di accedere al segmento dei dati in combinazione con il registro indice SI (ma anche DI e BX). In pratica, la memoria è suddivisa in blocchi, detti appunto segmenti, da 64KB (quelli che posso indicizzare direttamente con i 16 bit del registri di indice) con i registri di segmento definisco dove questo ha inizio.
Fin qui nulla di strano, essendo questa una tecnica già utilizzata dai processori che avevano un'ampiezza del bus di indirizzamento più ampia rispetto alla dimensione dei registri. La logica avrebbe voluto che l'indirizzo fisico (lineare) fosse calcolato come concatenazione tra il valore del registro segmento con quello di indice, ottenendo un valore su 32 bit di cui, i 12 bit più significativi venivano bellamente ignorati. La bizzarra scelta dei progettisti IBM (che procurò non pochi mal di testa agli sventurati programmatori) fu invece la seguente: il registro di segemento viene moltiplicato per 16 (in algebra binaria corrisponde a shiftare di 4 posizioni verso sinistra il valore, quindi buttare via i 4 bit più significativi e aggiungere quattro zeri sulla sinistra) e quindi sommare al risultato il valore del registro indice. Questo arzigogolo mentale fa si che la memoria invece di essere suddivisa in 16 segmenti da 64KB (risultato che si sarebbe ottenuto concatenando i due registri, ignorando i bit più significativi del risultato), è suddivisa in realtà in 4096 segmenti (sempre da 64KB!!!) tra loro ovviamente sovrapposti. Ogni segmento è separato dal successivo da 16 byte, blocco a cui viene dato il nome di paragrafo (delirio!!!!).

Facciamo un esempio per capire meglio. Supponiamo di avere in DS il valore B800h (valore espresso in notazione esadecimale) e in SI di avere il valore 0000h. Applicando la formula precedete, otteniamo l'indirizzo fisico su 20 bit:

B800h * 16 + 0000h = B8000h + 0000h = B8000h

Se non vi fidate dei conti, armatevi di calcolatrice e verificate da voi :o)

Quello che però voglio farvi notare è che, la coppia di valori B800:0000 (segmento:indice) non è l'unica che da origine a quell'indirizzo finale poichè, ad esempio, B000:8000 da esattemente lo stesso risultato:

B000h * 16 + 8000h = B0000h + 8000h = B8000h

Facendo due conti vi renderete facilmente conto che sono esattemente 4096 le diverse combinazioni segmento:indice che producono lo stesso risultato.

A questo punto non voglio scendere troppo nel dettaglio ma, penso che risulti abbastanza chiaro come avere valori diversi che generano gli stessi risultati possa generare non poca confusione. Tra l'altro, l'utilizzo di questa tecnica "ingurgitava" diversi cicli macchina per il calcolo dell'indirizzo fisico che, sommati all'utilizzo del multiplexing dati/indirizzi, rendeva le operazioni di accesso alla memoria tutt'altro che efficienti.

Schema del processore

Vista la relativa semplicità dell'8086, mi permetto di porporvi lo schema logico del processore così come fu concepito dagli ingegneri IMB più di trent'anni fa.


Dallo schema si notano:

  • i bus di cumunicazione interni, per i dati (8) e per gli indirizzi (4), ed i bus per i segnali verso la memoria e le periferiche (10, 11, 12)
  • i registri di uso generale e di indice (1), ed i registri di segmento e l'instruction pointer (2)
  • la logica per il calcolo dell'indirizzo fisico (3)
  • l'unita aritmetico logica per eseguire le elaborazioni (9)
  • la coda di fetch delle istruzioni (5) e l'unità di controllo del flusso di esecuzione (6)
  • la logica di controllo per l'accesso al bus esterno (7), che si occupa, ad esempio, della multiplexing dei segnali
  • il registro di stato (F)
Per fare un esempio, l'istruzione

    MOV AX, [BX]

copia il valore di AX nell'indirizzo di memoria DS:BX. Seguendo il flusso dell'istruzione sullo schema precedente, per prima cosa il valore del registro BX viene combinato con il valore in DS dalla logica di calcolo dell'indirizzo lineare (5). Il valore così calcolato viene passato alla circuiteria per il controllo del bus (7) che va poi ad indirizzare la memoria utilizzando l'address bus (10 e 11). A questo punto il valore in AX viene passato, tramite il data bus, interno al componente 7, per andare a salvare in memoria il valore (bus 11).

In fondo non è così complicato :o)

Miscellanea

In questo paragrafo, alcune notizie in ordine sparso:

  • il primo 8086 aveva una frequenza operativa massima di 5MHz, mentre le successive versioni erano in grado di operare a 10MHz
  • nel 1979, Intel lancia l'8088, versione economica (e abbastanza "sfigata") del suo processore, con data bus a 8-bit
  • nel 1980 viene rilasciato l'8087 coprocessore che estendeva le capacità dell'8086 permettendogli di effettuare operazioni in virgola mobile (floating point) su valori di 80 bit
  • il primo personal computer basato sull'8086 fu Mycron 2000 (1980). Per quanto riguarda il panorama italiano e la mia esperienza personale non posso dimenticare il mitico Olivetti M24, prodotto dalla casa eporediese a partire dal 1983
  • fino al 2002, la NASA utilizzava l'8086 come processore per le operazioni di manutenzione delle Space Shuttle Discovery
 
Il Mycron 2000 ed il mitico Olivetti M24


Conclusioni

Bene, siamo giunti alla fine di questa lunga cavalcata che ci ha permesso di conoscere un po' meglio il capostipite dell'architettura x86 che, nonostante alcuni demeriti, è riuscita nel tempo a "sotterrare" tutti i suoi concorreti. Penso che oggi non esista un personal computer non basato sull'architettura partorita da Intel nel lontano 1976 ... fino ad un po' di anni fa resistevano i Mac, ma dal 2006 anche la casa di Cupertino si è convertita, abbandonando i PowerPC.

Comunque la si pensi, è un pezzo di storia che merita di essere ricordato.

Alla prossima ...

11 commenti:

  1. beh... a proposito dei profughi che crearono lo Z80 da una costola, ma diciamo pure dall'intera gabbia toracica dell'8080, c'è una storia analoga che riguarda la nascita del Mos 6502, una cpu che governò molti dei primi home computer ad 8 bit (Vic-20, Apple II, Atari 400/800). Ebbene, questa famosa CPU, nota per lo più per essere economica e facile da programmare sebbene piuttosto lenta, fu progettata dallo stesso team che realizzò il Motorola 6800, non il ben più blasonato 68000. Ad ogni modo, il team lasciò la Motorola e con il knowout acquisito sviluppò il 6502, da cui discesero poi il 6510 del Commodore 64, il 7501 del Plus 4, l'8502 del Commodore 128, l'hu6280 del Nec PC-Engine, il CSG 4510 del Commodore 64DX/65 ed infine il 65c816 (a 16 bit) dell'Apple II GS e del Super Nintendo.

    RispondiElimina
  2. Grazie Retrobert per la tua interessante storia e per partecipare attivamente a questo blog ... sei uno dei miei lettori più affezzionati!! Thanks a lot!!! :o)
    Tex

    RispondiElimina
  3. Zilog e MOS hanno tracciato una tappa storica nello sviluppo informatico ed hanno reso quei tempi tra i più epici...al contrario dei tempi "freddi" informatici odierni.

    RispondiElimina
  4. Francesco:
    Secondo me erano tempi epici perchè era l'avanguardia della tecnologia e tante aziende si spaccavano le corna per ottenere il miglior processore (Zilog, MOS, Motorola, Intel, Texas Istruments) ... ora il mercato e piatto e quindi sicuramente meno emozionante!!!

    RispondiElimina
  5. Una curiosità: l'IMSAI8080 l'ho visto usare nel film WARGAME con Mattew Broderick...ma tutti quegli interruttori a cosa servivano?

    RispondiElimina
  6. Francesco:

    I primi computer non ricevevano i comandi utente tramite tastiera ma utilizzando degli interruttori come quelli che puoi vedere nell'immagine relativa al IMSAI8080. Stesso discorso per i risultati che si "evincevano" in base alla configurazione (acceso/spento) dei led presenti sul case. Gli stessi programmi venivano digitati su apposi terminali che poi producevano le decine di schede perforate che si utilizzavano per caricare il programma sull'elaboratore (ti lascio immaginare la facilità del debugging!!!
    Il primo computer a prevedere l'utilizzo di tastiera e video fu, spero di non dire castronerie, il mitico Apple I di del dinamico duo Jobs & Wozniak. Bei tempi :o)

    RispondiElimina
  7. Com'è che allora oggi ci siamo complicati la vita peggiorandola qualitativamente? :(

    RispondiElimina
  8. Vabbe' ... adesso non esageriamo! Tu sei uno di quelli "Si stava meglio quando si stava peggio" :o)

    RispondiElimina
  9. Beh! non sono io quello che ha detto qualche tempo fa...." per mandare una navicella sulla luna bastò una potenza di calcolo pari a due commodore 64...ora un pentium 4 non riesce a far girare come si deve Windows XP.. Qualcosa dev'essere andato storto!"... Condivido in pieno questa citazione! :D

    RispondiElimina
  10. Eheheheh ... questo è vero ... anche se sulla luna secondo me non ci siamo andati, è tutta una bufala ... sono un complottista io!! :o)
    Guarda, il problema dei computer di oggi è nel contempo il suo maggior difetto e nel contempo il suo maggior pregio ... il fatto di essere sistemi aperti che si possono continuamente upgradare ... di conseguenza chi scrive software lo scrive sempre per la macchina più recente, fregandonese dei sistemi più "anziani". Con il C64, l'Amiga, l'MSX si riuscivano a fare delle figate pazzesche sfruttando al massimo hw perche' il sistema era chiuso e non cambiava per anni (oggi esce una scheda video nuova ogni 15 giorni). La stessa cosa vale per la console ... guarda Tekken I e Tekken III per PSX, sembra impossibile che girino sullo stesso hardware, eppure è così.

    Io penso sia quello il problema dei moderni computer, lo scarso impegno di chi scrive il software non la potenza della macchina.

    RispondiElimina
  11. Eh! Pensa che la prima XBOX fu una specie di "ripiego" ad un'idea di Micosoft praticamente "linciata a sangue" dai produttori di hardware: ovvero quella di realizzare un S.O. standard in boot che consentisse esclusivamente di giocare col PC, isolando quindi Windows, che riduce la prestazioni reali di un PC del 70%. In pratica con questo S.O. un comune e non aggiornato pc poteva diventare una potente console game.
    Ti lascio immaginare le minacce e lettere minatorie da parte dei produttori hardware di tutto il mondo che avrebbero rallentato non poco la loro corsa all'ultimo micron.

    Ed ecco spuntare fuori un bel giorno la prima XBOX, la quale altro non era che un pc con Celeron 700, 64MB di RAM e un chip NFORCE della NVIDIA che gestiva grafica e sonoro.
    Bella storia vero? Una cosa buona stava per entrare in commercio l'hanno distrutta manco fosse una minaccia umanitaria!

    RispondiElimina