Total Hack Cheat
Benvenuto/a su Total hack Cheat....
non aspettate altro tempo Registratevi!!

Parte 4 guida linguaggio C

Vedere l'argomento precedente Vedere l'argomento seguente Andare in basso

Parte 4 guida linguaggio C

Messaggio Da RaYoZ il Gio Mag 20, 2010 12:16 pm

ACCENNI HARDWARE 8088/86 E INTERRUPTS


Accenni all' hardware del sistema 8088/86

Alcune persone si domanderanno il perche' a questo punto compaia
un capitolo dedicato all'hardware.
I linguaggi come il basic sono stati fatti per le persone che non hanno nessuna intenzione di interessarsi a come effettivamente il sistema gestisca le sue risorse.
Nel contesto di un discorso di programmazione a basso livello, quale quella eseguita mediante lo sfruttamento delle risorse hardware, la conoscenza di quest'ultimo e' indispensabile.
Ora chiaramente saremo distanti dal fare un trattato di progettazione di un sistema a microprocessore ma perlomeno un infarinatura, nel caso che gia' non la si abbia', e' necessaria almeno per far comprendere concetti normalmente utilizzati nella programmazione a questo livello.



Architettura di sistema

Escludendo per ora la trattazione relativa alle varie periferiche e alla programmazione di queste facciamo un discorso relativo alla struttura essenziale di un sistema.
Fondamentalmente un computer e' costituito da sei blocchi.


-----------------------------------------------------------------
ADDRESS BUS
------+ +------------------+ +-------------------+ +-------
: : : : : :
+---------+ +---------+ +---------+
: : : : : :
: +------------+ +-------------+ :
: CPU : CONTROL : MEMORY : BUS : I/O :
: +------------+ +-------------+ :
: : : : : :
+---------+ +---------+ +---------+
: : : : : :
------+ +------------------+ +-------------------+ +-------
DATA BUS
-----------------------------------------------------------------

La CPU e' in pratica il cuore del sistema in quanto tutte le
operazioni logiche aritmetiche vengono svolte al suo interno.
La CPU 8088/96 possiede un set di registri a 16 bit che hanno i
seguenti scopi.


Come gia' accennato precedentemente esistono 4 registri ad uso generale e precisamente AX, BX, CX e DX.
Oltre a questi ritroviamo due registri indici di stringa e precisamente SI (indice sorgente) e DI (indice destinazione) che vengono utilizzati per puntare alla stringa di dati in memoria.
Il registro puntatore di stack SP e' utilizzato per implementare una catasta hardware.
Per integrare quest'ultimo puo' essere utilizzato il registro BP (base pointer).
Il registro IP (istruction pointer) serve al processore per poter puntare all'istruzione successiva che deve essere eseguita.
Un breve discorso lo merita lo stack o pila.
L'evoluzione dei microprocessori ha portato negli anni a modificare il concetto, a livello fisico, di stack.
Nei primi processori l'implementazione dello stack era a livello hardware all'interno del processore stesso.
Questo infatti era una pila di registri organizzati con accesso seriale e cioe' l'acceso ai dati era possibile solo con quelli "superficiali".
Questo modo di utilizzare lo stack dava seri problemi in quanto l'inserimento di un dato su questo faceva si che quelli gia' presenti shiftassero verso il fondo.
Nel momento in cui il programmatore non teneva un conto preciso del numero di dati inseriti, capitava che quelli in fondo allo stack si perdevano in quanto "uscivano" da questo.
Le seguenti generazioni di processori adottarono uno stratagemma,
spesso anche questo inefficace, per far si che il programmatore potesse testare lo stato dello stack.
La soluzione adottata di fatti contemplava la presenza di un flag (bandierina) che segnalava lo stato dello stack.
Come dicevo anche questa soluzione spesso risultava inefficace in quanto era sempre compito del programmatore testare lo stato del flag di stack.
La soluzione ideale, quella adottata anche dai processori 8088/86, fu' quella di tenere lo stack esterno in memoria e non piu' all'interno del processore.
In questo modo il programmatore mediante l'uso di uno dei registri di segmento e precisamente SS (stack segment) puo' crearsi in una certa area di memoria lo stack adatto alle sue esigenze e al limite, mediante apposite opzioni in fase di link o mediante programmi particolari, modificare le dimensioni di questo.
Il registro che effettivamente indirizza lo stack e' SP.SP viene inizializzato a puntare alla prima locazione dello stack e ad ogni operazione di caricamento in questo viene automaticamente incrementato a puntare alla locazione successiva.
In corrispondenza di un istruzione di prelevamento dallo stack il registro SP viene decrementato e quindi viene letta la la cella indirizzata.
In altre parole, come detto prima, vale la regola "primo entrato ultimo uscito".

Parlando di variabili locali abbiamo gia' portato un esempio di utilizzo dello stack.
La manipolazione dei dati inseriti sullo stack e' una delle cose fondamentali nel momento in cui si agisce e si modificano i vettori di interruzione.
Sull'argomento diremo tutto a suo tempo.
L'assembler utilzza lo stack anche per memorizzare gli indirizzi presenti nei registri di segmento e nel registro IP nel momento in cui viene eseguita

una call con ritorno.
In altre parole e' chiaro che se il programma richiede un salto il registro puntatore di istruzione deve essere aggiornato con quello relativo alla destinazione.
Se il processore non salvasse da qualche parte il vecchio valore del registro IP non si potrebbe verificare un ritorno dopo l'esecuzione della chiamata.
A questo punto possiamo parlare anche del concetto di segmentazione argomento, probabilmente, nuovo per tutti gli utenti di sistemi a 8 bit.
All'interno del processore 8088/86 ritroviamo 4 registri incaricati di mantenere memorizzati i vari segmenti relativi al codice, ai dati e allo stack.
Per capire effetivamente cosa si intende per segmento vediamo di trattare il tutto a livello hardware.
Alcuni dei blocchi che comparivano sulla schematizzazione simbolica del sistema erano costituiti dai vari BUS.
Le operazioni svolte dal processore sono guidate da istruzioni allocate in memoria.
Questo significa che gran parte del lavoro svolto dal processore e' appunto l'inserimento e il prelevamento di dati per e da questa.
Lasciamo da parte un attimo il sistema 8088/86 e generalizziamo

il concetto di indirizzamento di memoria su un sistema astratto dotato di un banco di memoria di 64 Kbytes.
Il processore per le funzioni di trasferimento dalla e per la momoria si supporta del DATA BUS.
Questo in pratica e' costituito da una serie di conduttori sui quali i dati viaggiano in parallelo.
L'ADDRESS BUS e' concettualmente simile al DATA BUS solo che su questo scorrono i segnali relativi agli indirizzi interessati nelle operazioni di trasferimento.
Nel nostro sistema astratto l'ADDRESS BUS e' costituito da 16 bit.
Da questo fare il calcolo della memoria indirizzabile e' una cosa banale.
In pratica basta elevare a potenza la base numerica, cioe' il numero dei valori che potra' assumere ogni segnale , con il numero dei segnali presenti.
La base numerica e' in questo caso 2 (binaria) in quanto ogni singolo segnale potra' assumere i valori di 0 o di 1.

Il numero dei segnali presenti e 16 (il numero dei conduttori del'ADDRESS BUS) e quindi

2 ^ 16 = 65536

e cioe' 64 Kbytes.
Ora il tutto sarebbe molto semplice se si disponesse di un solo chip di memoria di queste dimensioni.
In questo caso, supponendo che il processore voglia leggere il contenuto della cella 2000, le operazioni svolte sarebbero le seguenti.

1) Immisione sul ADDRESS BUS del valore corrispondente all'indirizzo 2000 (0000011111010000).
2) La memoria che riceve questo segnale dovrebbe prendere il contenuto della cella relativa e immetterlo sul DATA BUS dove il processore provvederebbe a leggerla.

Purtroppo a questo punto sorge un problema.
Come fa' la memoria a sapere se l'indirizzo presente sul ADDRESS BUS e'relativo a un operazione di inserimento o di prelevamento dalla cella indicata ?
A segnalare questo ci pensa il processore sfruttando un altro dei blocchi segnalati nello schema iniziale e precisamente il CONTROLL BUS.
Mediante questo il processore prima di inviare l'indirizzo emette un segnale di R/W (read/write) che indica alla memoria la natura dell'operazione da svolgere.
A questo punto, quando tutto sembrava spiegato, sorge un altro problema.
Noi abbiamo schematizzato la memoria come un unico blocco di 64 Kbytes ma in effetti questa e' composta da un certo numero di chip.
Come sono montati questi chip sulla scheda ?
Pensare di inserire un ADDRESS BUS per ogni chip sarebbe assurdo.
La soluzione optata e' stata quella di montare tutti i chip i parallelo sullo stesso ADDRESS BUS.
Supponiamo per esempio che il banco da 64 Kbyte sia composto da 4
chip da 16 Kbyte.
Il numero dei chip in cui e' suddivisa la memoria totale non ha importanza in quanto il concetto e' valido indipendentemente dal numero di questi.
Opto per una soluzione di questo tipo solo per comodita' grafica relativa all'esempio.
Dicevamo che il processore dopo aver segnalato il tipo di operazione da compiere sulla memoria inserisce l'indirizzo relativo alla cella interessata sull'ADDRESS BUS.
Essendo tutti i chip in parallelo tra di loro come si fa' a indicare a quale chip e' relativo l'indirizzo ?

+-------+
16----:DECODER:----------------------------------------+
15----: :-------------------------+ :
+-------+----------+ : :
: CS 1 : CS 2 : CS 3 : CS 4
14----+---o---+------+---o---+------+---o---+------+---o---+
13----: :------: :------: :------: :
12----: :------: :------: :------: :
11----: :------: :------: :------: :
10----: C :------: C :------: C :------: C :
9 ----: H :------: H :------: H :------: H :
8 ----: I :------: I :------: I :------: I :
7 ----: P :------: P :------: P :------: P :
6 ----: :------: :------: :------: :
5 ----: 1 :------: 2 :------: 3 :------: 4 :
4 ----: :------: :------: :------: :
3 ----: :------: :------: :------: :
2 ----: :------: :------: :------: :
1 ----+-------+------+-------+------+-------+------+-------+
: : : :
R/W-------+--------------+--------------+--------------+


Considerando un esempio di questo genere ci accorgiamo che effettivamente per indirizzare i 16 Kbyte di ogni chip non sono necessari tutti e 16 i bit dell'ADDRESS BUS in quanto ne bastano soltanto 14.
Infatti facendo il calcolo

2 ^ 14 = 16384

e cioe' 16 Kbytes.
Per poter disporre di tutti i 64 Kbytes presenti sui 4 chip a questo punto ci serve soltanto un metodo per poter mandare uno di questi 16384 indirizzi possibili su uno di questi.
Gli ultimi due bit dell'ADDRESS BUS non sono inutilizzati in quanto vengono inviati su un decoder.
Non voglio trattare a fondo il concetto di decoder in quanto farlo e' inutile ai nostri fini.
Un decoder e' un circuito che riceve in ingresso una codifica binaria e che segnala quale numero sta' ricevendo attivando un'uscita diversa per ogni numero.
In questo caso il decoder ha 2 ingressi e quindi i numeri ricevibili

n formato binario sono esattamente 4 dati dalle varie combinazioni che possono assumere i segnali in ingresso.

Ingresso 1 2 : Uscita
-------------+-------
0 0 : 0
0 1 : 1
1 0 : 2
1 1 : 3


Da questo e' facile capire che mediante i 2 bit non utilizzati dell' ADDRESS BUS e' possibile attivare uno dei 4 chip.
Infatti ogni chip possiede un pin (piedino) chiamato di CHIP SELECT.
Supponiamo ora di voler indirizzare la cella 16383 ovvero l'ultima del primo chip (considerate sempre che si parte dall'indirizzo 0 relativo alla prima locazione).
L'indirizzo in binario immesso dal processore sull' ADDRESS BUS e' il seguente :

0011111111111111

I primi 14 bit dell'ADDRESS BUS sono in questo caso tutti a 1 mentre gli ultimi due a 0 (quelli che raggiungono il decoder).
Il decoder quindi ricevendo in ingresso 0 0 mette a 1 il primo piedino mandando il segnale di attivazione al pin di chip select del primo integrato.
Questo prelevera' l'indirizzo presente sui rimanenti 14 bit
dell'ADDRESS BUS indirizzando in questo modo la locazione 16383.
A questo punto l'indirizzo richiesto dal processore, sempre ad esempio, potrebbe essere 16384 che sommando la capacita' dei 4 chip risulterebbe essere la prima locazione del chip 2.Il processore immeterebbe in questo caso l'indirizzo in binario

0100000000000000

I primi 14 bit, tutti a 0, indicherebbero ai chip che la cella richiesta e' la prima.
In questo caso pero' i bit che raggiungono il decoder non sono piu' tutti a 0 ma il primo a 1 costringerebbe il decoder ad accendere il pin 2 relativo al secondo chip di memoria.
Il discorso non cambia continuando di questo passo. Spero che questo sia stato comprensibile.
Fate pure delle prove considerando magari piu' chip di capacita' minore.
Vi accorgerete che il discorso non e' diverso in quanto chiaramente un numero di locazioni minore per ogni chip pretende anche per il suo indirizzamento un numero minore di bit sull'ADDRESS BUS.
Tutti i rimanenti ad arrivare a 16 sarebbero utilizzati dal decoder che avrebbe, avendo piu' ingressi, la possibilita' di indirizzare piu' chip.
C'e' sicuramente chi si chiedera'.
Ma se un ADDRES BUS di 16 bit puo' indirizzare fino a 64 Kbytes come fa' un PC IBM o un M24 ad avere una memoria indirizzabile di 1 Mbytes ?
E' semplice.
Per poter accedere a una simile quantita' di memoria occorrono 20
bit sull'ADDRESS BUS.

2 ^ 20 = 1.048.576

Il metodo utilizzato e' essenziale per poter comprendere il concetto di segmentazione della memoria.
Il processore indirizza la memoria a blocchi di 64 Kbytes detti segmenti utilizzando una parola di indirizzo di 16 bit.
Come abbiamo accennato prima l'8088/86 possiede 4 registri di segmento (CS,DS,SS ed ES) che utilizza come indirizzo di partenza per contare da questo il numero di locazioni specificate dall'indirizzo a 16 bit.
Piu' precisamente il processore prende il valore di un registro di segmento, esegue uno shift a sinistra di 4 posizioni e gli aggiunge quello definito offset che altro non e' che l'indirizzo a 16 bit di cui abbiamo parlato.
In questo modo ottiene un indirizzo fisico a 20 bit.
Ogni segmento puo' iniziare ad ogni paragrafo ossia ad ogni blocco di 16 bytes.
Questo significa che un segmento potrebbe iniziare da locazioni tipo 0000H, 0010H, 0020H ecc.
L'offset, lo ripeto, e' la distanza di una certa locazione dall'inizio del segmento.
A questo punto solo piu' due parole riguardo l'uso dei registri di segmento.
CS e' il segmento di codice e contine le istruzioni che devono essere eseguite dal processore.
DS e' invece il registro di segmento dati atto a contenere dati di uso generale.
SS di cui abbiamo gia' parlato e' il segmento relativo allo stack.
Infine tra i registri di segmento ritroviamo anche l'extra segmente, ES, che puo' essere usato come area secondaria ad uso generale.
Possiamo aver concluso con questo il discorso relativo all'indirizzamento di memoria.
Spero di essere stato chiaro, anche se sicuramente lungo, almeno per quanto riguarda il discorso dei segmenti in quanto nei capitoli successivi, quelli che tratteranno gli interrupt, sara' un argomento ricorrente.
Ometto la descrizione accurata su uno dei blocchi riportati nello schema iniziale in quanto penso che tutti conoscano la differenza tra una memoria RAM e una ROM.
La memoria normalmente utilizzata dal processore per le sue operazioni e' quella RAM ossia una memoria in cui lo stazionamento dei dati e' momentaneo in quanto si tratta di una memoria di lettura/scrittura volatile e cioe' riscrivibile.
La ROM e' una memoria solo di lettura e viene utilizzata dal PC per il mantenimento della parte residente del BIOS (Basic Input Output System).
Il processore puo' utilizzare questa solo per operazioni di lettura.
Un esempio grafico relativo alla costruzione dell'indirizzo fisico e' il seguente.


16 1
+-----------------+
: OFFSET :
+-------+--+------+
16 : : 1
+-----------: :-+----+
: SEG REG : : :0000:
+-----------: :-+----+
: : : :
: : : :
+-------------+
\ + /
+---------+
: :
20 : : 1
+-----------------------+
: INDIRIZZO FISICO :
+-----------------------+


Con questo concludo il discorso relativo all'indirizzamento di meoria e alla segmentazione.
L'unico blocco di cui non abbiamo accennato nulla e' quello relativo all' I/O per il quale sara' riservato un apposito spazio quando parleremo della gestione delle varie porte di un sistema 8088/86.

RaYoZ
Admin
Admin

Messaggi : 1040
Punti : 2245
Data d'iscrizione : 03.04.10
Età : 22
Località : immerso nei pensieri

Tornare in alto Andare in basso

Vedere l'argomento precedente Vedere l'argomento seguente Tornare in alto

- Argomenti simili

 
Permesso di questo forum:
Non puoi rispondere agli argomenti in questo forum