Capitolo 1.   Richiami sulle caratteristiche dei processori x86

Pur ribadendo che la conoscenza delle caratteristiche dei processori Intel x86 (e compatibili) è da considerare un prerequisito per l'uso di queste dispense, in questo capitolo riassumiamo le loro caratteristiche fondamentali.

1.1   Architettura dell'8086

Il processore 8086 ha le seguenti peculiarità:

Essendo la gestione della memoria segmentata, gli indirizzi si indicano nella forma: regseg:offset, cioè: indirizzo di segmento : indirizzo della cella all'interno di quel segmento, ricordando che i valori si esprimono preferibilmente in esadecimale.

Ricordiamo inoltre che la memoria gestita è di 1 MB suddivisi in 65.536 segmenti da 64 KB ciascuno, parzialmente sovrapposti (ognuno inizia 16 locazioni di memoria dopo il precedente); di conseguenza una stessa cella fisica può essere individuata da molti indirizzi segmentati diversi.

Per calcolare l'indirizzo effettivo associato a un indirizzo segmentato, come ad esempio a0e3:1b56, occorre effettuare un semplice calcolo: si moltiplica per 16 l'indirizzo del segmento (a questo scopo basta aggiungere uno zero alla sua destra) e poi si somma con l'offset.

Applicando la regola all'indirizzo prima citato dobbiamo sommare a0e3016 e 1b5616 ottenendo a298616.

Nella CPU 8086 abbiamo i seguenti 14 registri che hanno un'ampiezza di 16 bit:

Nel registro di stato solo 9 dei 16 bit sono significativi (vedi figura 1.1) e si dividono in:

Figura 1.1.

figure/cpu-schema-flags

Vediamo in dettaglio il ruolo di ogni singolo flag:

Notiamo che, quando si usano i flag del registro di stato, cioè nelle istruzioni di salto condizionato, si fa riferimento solo alla prima lettera del loro nome (ad esempio il flag di zero è identificato solo con z).

1.2   Novità dell'architettura IA-32 e IA-64

Con IA-32 si ha il passaggio a 32 bit dell'architettura dei processori; il capofila della nuova famiglia è stato l'80386, che ha portato molte novità riguardanti i registri e la gestione della memoria, pur mantenendo inalterate alcune caratteristiche (ad esempio la non ortogonalità, la gestione delle periferiche):

La successiva evoluzione verso i 64 bit, con l'architettura x86-64, ha portato l'ampiezza dei registri, appunto, a 64 bit con le seguenti caratteristiche:

Riguardo alla memoria rimane la possibilità di gestirne 1 MB in modo segmentato come nell'8086 (si dice allora che si lavora in modalità reale); la novità è però la modalità protetta nella quale si gestiscono 4 GB di memoria con indirizzi nella forma selettore:offset chiamati indirizzi virtuali.

Questo nome dipende dal fatto che non è detto che tali indirizzi corrispondano a reali indirizzi fisici di memoria (solo da poco tempo i comuni Personal Computer hanno una dotazione di memoria centrale di qualche GB); i processori sono infatti in grado di gestire la memoria virtuale con un meccanismo detto di paginazione dinamica sfruttato poi in modo opportuno anche dai moderni sistemi operativi.

Questo argomento richiederebbe notevoli approfondimenti che però esulano dagli scopi di queste dispense.

Concludiamo citando la presenza della tabella dei descrittori, alle cui righe si riferiscono i registri selettori, che contiene indirizzi iniziali e dimensioni dei vari segmenti; questi ultimi hanno infatti dimensione variabile (massimo 4 GB).

Di ogni selettore solo 13 dei 16 bit sono usati per individuare una riga della tabella; i segmenti sono quindi al massimo 8192.

Gli indirizzi virtuali nella forma selettore:offset con offset a 32 bit, vengono tradotti in indirizzi lineari a 32 bit che, come detto, non è detto che corrispondano direttamente a indirizzi fisici di memoria.

Lo spazio virtuale effettivamente a disposizione di ogni processo è comunque di soli 3 GB perché la zona più alta, ampia 1 GB, è uno spazio comune a tutti i processi in esecuzione e riservata al kernel di Linux.