Sezione

Indirizzi Base Registri Interni
Area Comunicazione BIOS Funzioni BIOS Funzioni DOS
Prefazione Capitolo 1 Capitolo 2 Schede
Libreria ASM Libreria MAC Palestra Progetti ASM
Info Download INDICE

Capitolo 1

Home » Programma il Computer » Tutorial Assembly

Capitolo 1 - Il processore - Il Debugger

  Il Processore e il Debugger

PROCESSORE 80x86 9/14 [20 di 60] 

    

    I Registri di Segmento - Indirizzi Logici e Indirizzi Fisici
     
bulletIl processore 8086 prevede 4 registri di segmento (Segment Registers); il loro nome è CS, DS, ES e SS, tutti a 16 bit, indivisibili.
bulletIl concetto di segmento è presente in moltissime pagine di questo sito per cui un link univoco all'argomento sembra impossibile; è più semplice ribadire che si tratta di un'area di memoria di 65536 (64k) locazioni consecutive, utilizzata dal sistema per allocare i programmi, in attesa di ceder loro il controllo.
bulletA questo proposito è utile leggere l'argomento Come viene trattato il file EXE dal Loader del DOS del Capitolo 2, che sottolinea come una importante caratteristica dei files EXE consiste nel poter disporre di una quantità di memoria grande fino a 4 segmenti, di solito, associati al codice (e puntati con CS), allo stack (SS), ai dati (DS) e ad altri dati extra (ES).

      

bulletRisulta comunque chiaro che i registri di segmento servono per individuare le rispettive aree da 64k, nelle quali si svolgono attività vitali per la vita dei programmi in esecuzione

      

bulletUn altro concetto chiave legato a questi registri è quello di indirizzo logico e indirizzo fisico. Il problema è sorto fin dall'inizio: i progettisti dell'8086 si sono trovati a gestire un bus d'indirizzi di 20 linee con registri a 16 bit; in pratica era evidente la necessità di porre un indirizzo valido sul rispettivo bus ma non era possibile farlo perchè gli strumenti a disposizione (registri) erano troppo piccoli.
bulletDa questa esigenza è nata la tecnica della segmentazione della memoria, un abile sotterfugio per poter puntare ogni indirizzo con 2 registri a 16 bit:
bulletil primo (detto appunto registro di segmento) individua un'area di 64kBytes consecutivi, dentro lo spazio indirizzabile del processore, ed è uno di quelli descritti un questa pagina.
bulletil secondo (detto registro di offset) è in grado di scorrere ciascuna delle 65536 locazioni contenute nel segmento, in virtù dei diversi possibili valori che può assumere (essendo a 16 bit, 216=65536=64k), ed è uno di quelli descritti della pagina seguente (per poter continuare la descrizione ne prenderemo in prestito uno, il registro puntatore d'istruzione IP).

      

bulletDunque con un indirizzo logico, cioè con una coppia di registri di tipo Segment:Offset, per esempio CS:IP (notare la forma con cui si esprime l' indirizzo logico) è possibile ottenere un indirizzo fisico; basta imparare il meccanismo che la CPU usa, internamente, per ricostruirlo.

      

Suggerimento L'indirizzo fisico (cioè il numero binario a 20 bit che sarà posto sul bus address) si ottiene sommando il valore di un registro di segmento moltiplicato per 16 con il valore di un registro di offset; la coppia di registri a 16 bit coinvolta nell'operazione può essere messa in evidenza nella forma Segment:Offset, cioè nella forma tipica di un indirizzo logico.

      

bulletDa notare che, per rendere leggibili gli indirizzi (sia fisici che logici), è prassi comune accorpare i bit a 4 a 4, sostituendo ogni quaterna con un simbolo del sistema di numerazione esadecimale:
bullettali simboli sono sedici (appunto exadeci..): i numeri da 0 a 9 e le lettere da A a F
bulletciascuno di essi è dunque codificato da 4 bit (cioè è codificato dall'unità di misura logica detta nibble = 4 bit)
bulletcosì per esempio 00010010010001000000 (numero assurdamente illeggibile, espresso in binario) diventa 12440, espresso in esadecimale
bulletper distinguere con certezza il tipo di codifica utilizzato per esprimere l'informazione si aggiunge una H (per Hexad...), cosicché 00010010010001000000 (binario) = 12440H (in esadecimale)

      

bulletLo schema seguente mostra questa tecnica: si osserva che moltiplicare per 16 significa aggiungere a destra del valore esadecimale del registro di segmento 4 bit di valore nullo (un nibble uguale a 0):

      

   Indirizzo fisico (20 bit) = Registro di Segmentox16+Registro di Offset   

  Se CS=1234H e IP=0100H
dall'indirizzo logico CS:IP si ricava l'indirizzo fisico:
   
   
CS*16 +  1234H*10H +  12340H +
       IP =      0100H =   0100H =
   ----------------------------------
  indirizzo fisico >>>   12440H

      

bulletVa sottolineato che, per ogni indirizzo fisico, i valori dei 2 registri Segment:Offset che concorrono a definire l'indirizzo logico possono assumere numerosissime combinazioni (in pratica ben 65536..); lo schema seguente mostra altre 5 possibilità:

      

 10000H +
  2440
H =
---------
 12440
H

 11110H +
  1330
H =
---------
 12440H
 12000H +
  0440H =
---------
 12440H
 11FF0H +
  0450H =
---------
 12440H
 12440H +
  0000H =
---------
 12440H

      

bulletLa scelta dei valori da associare ai 2 registri è dunque del tutto irrilevante; personalmente preferisco quella proposta per ultima, nell'esempio precedente, che lascia nel registro di offset un numero 0000H e in quello di segment la parte rimanente: è la proposta più vicina alla logica della memoria segmentata, nella quale l'offset punta l'inizio (0000H) del segmento a sua volta puntato dal segment (1244H).
bulletPer facilitare l'esercizio mentale legato a questa conversione è disponibile l'eseguibile Calcola.COM, che puoi scaricare o eseguire cliccando qui.

      

      

bulletDei registri di offset parleremo nella pagina successiva; in questa riassumiamo i compiti dei 4 registri di segmento; di solito è il Loader (caricatore dei programmi in memoria) del Sistema Operativo che si occupa di caricare in questi registri i valori corretti per l'esecuzione del programma stesso:

      

bulletCS, Code Segment: punta l'area di 64k destinata a contenere i bytes del codice eseguibile, la traduzione in linguaggio macchina delle nostre istruzioni; in ogni momento (insieme a IP, come vedremo) punta il codice operativo dell'istruzione che sta per essere eseguita. Non esistono istruzioni per cambiarne direttamente il valore, sebbene la cosa sia possibile, in modo indiretto, correttamente con  JMP ,  CALL o  RET  e impropriamente (e a rischio) con la coppia  PUSH rS / POP CS . Se si desidera avere una copia del valore di CS, per esempio in AX, possiamo usare senza danno la sequenza di istruzioni  PUSH CS / POP AX .

      

bulletSS, Stack Segment: punta l'area di 64k destinata a contenere i bytes destinati allo stack, l'area nella quale il processore annota gli indirizzi a cui tornare in caso di esecuzione di  CALL o  INT ; in ogni momento (insieme a SP, come vedremo) punta la prima locazione disponibile ad essere utilizzata. Modificare il valore di questo registro è assurdo e sconveniente: il risultato è il probabile crash del programma in esecuzione (se non del computer stesso).

      

bulletDS, Data Segment: punta l'area di 64k destinata a contenere i dati del programma in esecuzione e può essere modificato senza rischio dal programmatore, per esempio con la sequenza di istruzioni  MOV AX,nnnnH / MOV DS,AX  o con la coppia  PUSH AX / POP DS ; numerose istruzioni danno per scontato che questo sia il registro di segmento delle locazioni sorgente ( MOVS ,  LODS ) dei dati da esse trattati.

      

bulletES, Extra Segment: punta l'area di 64k destinata a contenere i dati del programma in esecuzione (oltre a quelli puntati da DS) e può essere modificato senza rischio dal programmatore, per esempio con la sequenza di istruzioni  MOV AX,nnnnH / MOV ES,AX  o con la coppia  PUSH AX / POP ES . Di solito è utilizzato per puntare particolari zone di memoria: la sovrapposizione di un segmento ad una determinata area ne facilita la gestione (si pensi per esempio alla RamVideo); numerose istruzioni danno per scontato che questo sia il registro di segmento delle locazioni destinazione  ( MOVS ,  STOS ) dei dati da esse trattati. 

      

bulletCon l'avvento dei processori a 32 bit (cioè con bus dati interno, e quindi registri, a 32 bit), a partire dal 80386, i sistemi hanno cominciato a gestire la memoria con altre tecniche e il problema della segmentazione ha perso importanza; i registri di segmento sono utilizzati in 2 diverse modalità, dette real mode e protected mode.
bulletIn ogni caso, poichè la parte offset dell'indirizzo logico può essere ora anche a 32 bit, ciascun segmento può arrivare alla dimensione di 4 GBytes.

      

bulletIl primo dei 2 modi (real mode, che si rifà alla descrizione appena conclusa) è comunque garantito, per assicurare portabilità verso il basso, e sarà da noi ampiamente utilizzato con soddisfazione, specialmente per puntare le locazioni del primo mega di memoria, straordinariamente ricco di informazioni e zone utili.
bulletSolo per completezza,  a partire dal 80386 sono disponibili altri 2 registri di segmento, GS e FS, comunque a 16 bit.

    

Pagina Precedente Capitolo 1 Pagina Successiva PROCESSORE 80x86 9/14   Torna alla Home  del Capitolo1 del "Tutorial" Lezioni - Vai al DownLoad dei files DOC Torna al Menu del "Tutorial"
20 di 60
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60

    

CAP. 1 » 1. Processore 80x86 2. Istruzioni 80x86  3. Debug  4. La Grande Libreria
TUTORIAL » Indirizzi Base | Registri Interni | Area Comunicaz. BIOS | Funzioni BIOS | Funzioni DOS
Prefazione | CAP 1 | CAP 2 | Schede | Palestra
Libreria ASM | Libreria MAC | Progetti ASM | Download | Info | Indice
Home 
Pascal|Manuali|Tabelle|Schede
Tutorial Assembly|Palestra Assembler
Aggiungi Giobe®2000 ai preferiti  
Motore
Ricerca
  Rendi Giobe®2000 pagina di Default
© 2001-2010  -  Studio Tecnico ing. Giorgio OBER
Tutti i diritti sono riservati