prof. Nunzio Brugaletta | PC inside |
Per l'esecuzione di un programma in linguaggio macchina, una CPU esegue, iterativamente, un ciclo di fetch-decode-execute: preleva (fetch) una istruzione dalla memoria, la decodifica (decode) e la esegue (execute).
Nello schema sono riportati i componenti principali di una CPU:
L'interfaccia con i bus: il Memory Address Register e il Memory Data Register che permettono alla CPU di dialogare con le altre componenti.
Un bus interno che consente lo scambio di dati fra i vari componenti interni alla CPU e con i bus esterni (Internal Bus).
I registri generali utilizzati per depositare temporaneamente i dati su cui si stanno effettuando le elaborazioni.
L'ALU (Arithmetic Logic Unit) che effettua le operazioni aritmetiche e logiche.
L'Unità di Controllo che ha il compito di coordinare le altre componenti presenti nel processore. Per esempio abilita alla scrittura o alla lettura i vari registri, interpreta le istruzioni. Ad ogni ciclo di clock invia determinati segnali, in dipendenza dell'interpretazione dell'istruzione, utili per l'esecuzione di una istruzione. I segnali sono ricevuti dalle componenti interessate che possono, così, predisporsi in modo corretto al compito da svolgere.
Il registro PSW (Program Status Word) in cui viene registrato lo stato delle operazioni effettuate.
I registri IR (Instruction Register) e PC (Program Counter) per puntare all'istruzione corrente o alla prossima istruzione da eseguire.
Il ciclo fetch-decode-execute eseguito dal processore per ogni istruzione, si può esprimere, tenendo conto del ruolo dei registri:
Fase di fetch |
|
Fase di decode |
L'istruzione viene interpretata, prelevando eventualmente dalla memoria altri dati necessari se l'istruzione completa non è contenuta nel dato prelevato in precedenza. In ogni caso, alla fine, PC punterà all'istruzione da eseguire successivamente. |
Fase di execute |
Se, per esempio, l'istruzione da eseguire è una somma, i registri verranno caricati con i numeri da sommare e la CU invia alla ALU il comando per l'esecuzione della somma. La ALU esegue l'operazione: il risultato prodotto sarà conservato in uno dei registri e verrà aggiornata la PSW. |
Il ciclo viene ripetuto per la prossima istruzione fino a che non si arrivi ad una istruzione di halt.
La PSW o registro di stato conserva lo stato di alcune operazioni matematiche ed è un registro che funziona in modo particolare: ogni singolo bit ha un significato autonomo a differenza degli altri registri dove ha significato l'intera stringa binaria. Ogni singolo bit del registro di stato è un indicatore (flag) di un determinato evento che si è verificato nel corso dell'ultima operazione.
Di seguito si esaminano alcuni indicativi:
CF: Carry Flag o flag del riporto. Indica se l'operazione effettuata ha prodotto un risultato non contenibile nello spazio predisposto. Per esempio se si effettua una operazione a 16 bit, indica il riporto al 17-esimo bit.
OF: Overflow Flag. Indica se nell'operazione effettuata si è verificato un errore di overflow (risultato non rappresentabile nello spazio predisposto).
IF: Interrupt Flag. Abilita o disabilita le interruzioni. Ogni volta che è terminato un ciclo di fetch-decode-execute il processore può essere interrotto da una periferica; interruzione che non si può accettare durante le tre fasi che comportano l'esecuzione di una istruzione e che devono essere eseguite, anche se prevedono diversi accessi in memoria, come se fosse un unica operazione. Un interrupt da parte di una periferica comporta, se accettato, che la CU conservi lo stato del programma attualmente in esecuzione (il contenuto del PC e dei registri generali) in una apposita area di memoria (lo Stack di sistema), carichi nel PC l'indirizzo del programma di servizio dell'interruzione e, alla fine di questo, ripristini dallo stack i registri, in modo da continuare l'esecuzione del programma sospeso.
ZF: Zero Flag. Indica se il risultato dell'operazione effettuata è stato nullo.
SF: Sign Flag. Praticamente uguale al bit più significativo del risultato di una operazione, ne indica il segno.
Normalmente le istruzioni di un programma vengono eseguite in sequenza, ma, in presenza di strutture di controllo, la sequenza potrebbe essere modificata: si pensi, per esempio in C/C++, a strutture come if o for.
Gli ultimi due flag vengono utilizzati quando si tratta di effettuare salti condizionati.
... // istruzioni A if(alfa>beta) // istruzioni B else // istruzioni C // istruzioni D
Nel frammento di codice riportato, dopo l'esecuzione delle istruzioni A c'è una condizione che specifica, in dipendenza del risultato del confronto, quali istruzioni eseguire prime delle D: se la condizione è vera si eseguono le B e si salta alle D, se è falsa si salta alle C e quindi, in sequenza, si eseguono le D.
Per poter stabilire l'obiettivo del salto è necessario verificare il risultato del confronto. Il confronto viene risolto effettuando una sottrazione senza conservazione del risultato fra alfa e beta e consultando i flag di Zero e di Segno.
Considerando che ZF viene posto ad 1 se il risultato è nullo e SF viene posto ad uno se il risultato è negativo, esaminando il valore dei due flag, si possono avere indicazioni sul risultato del confronto:
Operazione |
SF |
ZF |
Risultato |
---|---|---|---|
alfa - beta |
0 |
0 |
alfa > beta |
0 |
1 |
alfa == beta |
|
1 |
0 |
alfa < beta |
http://ennebi.solira.org | ennebi@solira.org |