Con IA-32 (Intel Architecture 32 bit), a volte i386, si definisce l'architettura o l'instruction set dei microprocessori prodotti da Intel, AMD e altre compagnie minori per il mercato desktop a partire dal 1985, e che è presente nella grandissima maggioranza dei personal computer esistenti al mondo. Spesso viene definita un'architettura CISC, ma queste distinzioni stanno sempre più perdendo significato con l'avanzare della tecnologia.

Storia Il termine fu coniato per distinguere il set di istruzioni per le CPU compatibili con il processore Intel 80386 da quelli per serie incompatibili come Itanium. Il set IA-32 viene implementato in tutte le CPU della grande famiglia x86 successive all'80386, ovvero quelle a 32 bit. I programmi che sono utilizzati con uno di questi processori possono girare in modalità protetta, usare memoria maggiore di 640K, disporre di memoria virtuale e ambiente multitasking. Inoltre essi possono accedere ad uno spazio di memoria lineare di circa 4 GB.

Modalità di operazione dei processori IA-32 L'IA-32 supporta tre modalità di funzionamento: la modalità reale, la modalità protetta e la modalità 8086 virtuale. In modalità protetta i programmi possono sfruttare appieno il processore e tutta la memoria disponibile sulla macchina, mentre in modalità reale e in modalità 8086 virtuale il software ha a disposizione un solo megabyte di RAM e il processore si comporta come un semplice 8086.

Registri La CPU 80386 (e tutti i suoi successori) ha 4 registri ad uso generico a 32 bit e 6 registri di segmento, più il registro dei flag, due registri indice e due registri per la gestione dello stack. A questi registri di uso comune si aggiungono alcuni destinati a compiti particolari: ci sono 4 Control Register, 6 Debug Register e 4 Test Register, oltre naturalmente ai registri descrittori di segmento necessari per l'implementazione dei meccanismi di memoria virtuale. Il coprocessore matematico 80387 aggiungeva al sistema altri 8 registri in virgola mobile. I processori seguenti hanno incorporato il coprocessore matematico e introdotto altri registri per le istruzioni SIMD, come l'MMX, il 3DNow! e l'SSE, ma senza abbandonare mai il gruppo di registri originario del 386.

Registri ad uso generico I registri ad uso generico x86 non sono realmente destinati all'uso generico come indicherebbe la definizione, a causa di alcuni processi specifici che possono spesso essere eseguiti impiegando solo uno o due di questi registri. In altre architetture i registri ad uso generico sono impiegabili in modo assolutamente indistinto, mentre i registri x86 sono suddivisi tra specifici per i dati e specifici per gli indirizzi.

Inoltre molte operazioni possono essere svolte o in un registro o direttamente nella RAM, senza necessità di caricare i dati in un registro. Questo comportamento dimostra i trent'anni di età di quest'architettura.

Nota: con l'arrivo dell'estensione AMD64 all'architettura x86 questa caratteristica è stata eliminata, almeno in modalità a 64 bit: ora i registri ad uso generico sono realmente ad uso generico, senza distinzioni. Questo non influenza comunque l'architettura IA-32.

Registri a 8 e 16 bit È inoltre possibile l'accesso ad ulteriori set di registri a 8 e 16 bit. Per esempio, si può accedere ai 16 bit inferiori del registro a 32 bit EAX chiamandoli AX. Alcuni registri a 16 bit possono essere divisi ulteriormente in registri a 8 bit: la metà superiore del registro a 16 bit AX visto sopra è chiamata AH e l'inferiore AL. Allo stesso modo, il registro a 32 bit EBX si divide in BX (16 bit), ulteriormente diviso in BH (8 bit) e BL (8 bit).

Registri generici dei dati Tutti i seguenti registri possono essere impiegati per uso generico, ma anche per processi specializzati; ognuno di essi può essere suddiviso in registri a 16 o 8 bit.

EAX - accumulatore (specializzato per le istruzioni aritmetiche) EBX - base register (usato per indirizzare il dato nel segmento di memoria) ECX - contatore (specializzato per i cicli) EDX - data register

Registri degli indirizzi Usati solo per l'indirizzamento. Possono essere divisi in registri a 16 bit ma non a 8 bit.

EBP - base pointer (contiene l'indirizzo dello stack frame attualmente impiegato) ESI - source index (usato per le stringhe) EDI - destination index (usato per le stringhe) ESP - stack pointer (contiene il primo indirizzo di uno stack) EIP - instruction pointer (contiene l'indirizzo dell'istruzione successiva)

Registri stack per la virgola mobile Fin dall'introduzione dell'80486 sono presenti 8 registri x87 in virgola mobile, numerati da ST(0) a ST(7). Ogni registro contiene 80 bit e immagazzina numeri nel formato "precisione doppia estesa" dello standard IEEE 754. A questi registri non si può accedere direttamente, ma come uno stack LIFO. Il numero del registro non è fisso, ma si riferisce alla cima dello stack: ST(0) è il registro in cima allo stack, ST(1) è quello inferiore, ST(2) è ancora inferiore e così via. Questo significa che un dato è sempre spinto verso il basso, e che le operazioni vengono sempre effettuate con l'operando contenuto in cima allo stack: non è possibile accedere ad un dato registro in modo casuale, ma solo in ordine.

Registri di segmento I registri di segmento vengono utilizzati dall'80386 per generare un indirizzo lineare da un indirizzo logico. L'indirizzo logico è dato dalla coppia registro di segmento:offset (l'offset può essere una costante, un registro di base, di indice o la combinazione dei tre, con alcune regole/eccezioni). L'indirizzo lineare viene quindi trasformato in indirizzo fisico dal meccanismo di paging del processore.

I registri di segmento sono 6: CS - code segment (viene implicitamente utilizzato dal processore, in coppia con il registro EIP, per prelevare la prossima istruzione) DS - data segment (viene utilizzato, implicitamente, nell'accesso alla memoria da parte di un'istruzione) SS - stack segment (utilizzato in coppia con ESP per gestire lo stack) ES - extra segment (utilizzato come ulteriore registro per dati, simile al data segment) FS - extra segment (segmento extra per i dati, ad uso generico) GS - extra segment (segmento extra per i dati, ad uso generico)

Nota: I registri FS e GS furono aggiunti nell'80386 (nei processori precedenti non erano presenti) e il loro nome è una semplice continuazione dell'alfabeto dalla E di ES.

Nota: Quando si vuole far riferimento ad un indirizzo di memoria nell'architettura IA-32, viene utilizzata la forma <SEGMENTO>:<OFFSET>. Il segmento è espresso mediante uno dei 6 registri di segmento (anche se in alcuni casi è possibile esprimerlo con un valore costante) mentre l'offset indica lo scostamento all'interno del segmento. Le istruzioni, ad esempio, vengono sempre prelevate nella memoria all'indirizzo puntato dalla coppia CS:EIP.

Registro dei flag L'80386 dispone di un registro dei flags, chiamato EFLAG. Sebbene non sia direttamente accessibile mediante un nome (come EAX, ad esempio) è possibile in qualche modo leggerlo e scriverlo. Sono necessarie solo un paio di istruzioni:

/* Lettura dello stato del registro dei flags */ PUSHFD ;Salva lo stato dei flags nello stack POP EAX ;Estrae dallo stack e salva in EAX (o qualunque altro registro generale)

Per modificare, invece, lo stato dei flags sono necessarie le seguenti due istruzioni:

/* Modifica dello stato dei flags */ PUSH EAX ;Salva il registro EAX sullo stack (o qualunque altro registro generale) POPFD ;Estrae dallo stack e memorizza nel registro dei flags

Le istruzioni precedenti salvano e ripristinano lo stato di EFLAG (versione a 32-bit dei flags dell'80386). È possibile salvare/ripristinare solo i 16 bit meno significativi utilizzando PUSHF/POP AX e PUSH AX/POPF rispettivamente. La dimensione (16 o 32 bit) utilizzata dipende dalla dimensione dell'operando. Il prefisso di forzatura operando (op-code 0x66) permette di variare la dimensione all'interno del contesto corrente: se utilizzato in modo 16-bit farà trattare al microprocessore l'istruzione come a 32-bit e viceversa.

Il registro dei flags è un registro a 16 bit dove ad alcuni bit (o raggruppamento di essi) è assegnato un significato preciso ed indica lo stato del processore. Se il bit è posto ad 1 il flag è impostato (set), se posto a 0 si dice che è resettato (reset o clear).

I numeri indicano la posizione in bit le sigle indicano il nome simbolico del flag.

3130292827262524232221201918171615141312111009080706050403020100 V8RF NTPLPLOFDFIFTFSFZF AF PF CF

Significato dei flags: V8 - Virtual 86 mode (se impostato indica che si è in modalità Virtual-8086) RF - Resume Flag (se impostato abilita le eccezioni in modo debug) NT - Nested Task Flag (se impostato indica che il codice in esecuzione non deve essere interrotto dal multi-tasking in quanto routine di un servizio di interrupt) PL - Priviledged Level Flag (2 bits) (se impostato permette di eseguire istruzioni di I/O, in caso è resettato, l'esecuzione di istruzioni di I/O genera un'eccezione di protezione). OF - Overflow Flag (se impostato indica che l'ultima operazione aritmetica ha generato un overflow) DF - Direction Flag (indica alla cpu quale direzione utilizzare negli incrementi automatici delle istruzioni che operano su stringhe. IF - Interrupt Flag (se impostato indica alla cpu di rispondere agli interrupt. L'NMI-Non Maskable Interrupt non viene influenzato da questo flag) TF - Trap Flag (se impostato indica alla cpu di generare una INT 0 dopo ogni istruzione) SF - Sign Flag (se impostato indica che l'ultima istruzione aritmetica ha generato un numero negativo). ZF - Zero Flag (se impostato indica che l'ultima operazione logico/aritmetica ha generato uno 0) AF - Auxiliary Carry Flag (se impostato indica che l'ultima operazione aritmetica ha generato un riporto sui 4 bit inferiori di AL, usato nell'aritmetica BCD) PF - Parity Flag (se impostato indica che l'ultima operazione aritmetica ha generato un risultato formato da un numero dispari di bit posti ad 1) CF - Carry Flag (se impostato indica che l'ultima operazione aritmetica ha generato un riporto)

I restanti bit non sono utilizzati e vengono riservati ad uso futuro; il loro valore non dovrebbe essere modificato e, se letto, non dovrebbe essere preso in considerazione.

Registri SIMD

Gli instruction set MMX, 3DNow!, e SSE possiedono propri registri, in aggiunta a quelli standard IA-32.

Registri MMX LMMX possiede 8 registri, chiamati da MM0 a MM7 (da qui in poi MMn), che però sono fisicamente gli stessi registri x87 per il calcolo in virgola mobile della FPU, per cui è impossibile usare contemporaneamente le istruzioni MMX e quelle in virgola mobile: prima di usare il set di istruzioni MMX deve essere disabilitata la FPU, con una istruzione apposita.

Ognuno dei registri MMn contiene un intero a 64 bit, ma una delle caratteristiche fondamentali di questo instruction set è il concetto di vettore, formato da più dati simili tra loro: potevano quindi essere immagazzinate due parole di 32 bit l'una, quattro di 16 o otto di 8.

Sempre perché i registri MMn sono in "coabitazione fisica" con i registri x87, che contengono 80 bit l'uno, nell'esecuzione delle MMX i primi 16 bit del registro vanno sprecati: vengono quindi tutti impostati a 1, in modo che i dati presenti vengano riconosciuti come "NaN" o come infiniti da un'applicazione in virgola mobile, e rendendo facile riconoscere se vengano usati dati in virgola mobile o MMX.

Registri 3DNow! Il 3DNow! fu progettato come un'estensione naturale delle istruzioni MMX per il calcolo in virgola mobile; usa quindi le stesse denominazioni dei registri MMn, ma invece di immagazzinarvi parole di 64 bit, vi introduce numeri in virgola mobile a precisione singola.