Sistemi di numerazione ed elementi di logica



Ogni buon programmatore dovrebbe conoscere almeno 2 sistemi di numerazione oltre quello decimale imparato alle scuole elementari: il sistema BINARIO e quello ESADECIMALE.
Il sistema di numerazione binario è particolarmente legato ai calcolatori in quanto essi possono riconoscere solo segnali aventi due valori : uno alto e uno basso ; per cui si associa al valore alto la cifra binaria 1 e a quello basso la cifra binaria 0 (oppure H e L, o ancora VERO e FALSO).
Infatti nel sistema binario esistono solo due cifre 0 e 1 appunto e i numeri ma anche tutte le altre informazioni vengono rappresentate con sequenze di Zero e di Uno.
Il sistema di numerazione binario è un sistema posizionale come quello decimale, cosa vuol dire: consideriamo il numero decimale 237 , esso può essere scomposto in questo modo:

237 = 2 * 10^2 + 3 * 10^1 + 7 * 10^0

ossia le cifre del numero vengono moltiplicate per le potenze di dieci (da cui decimale) crescenti da destra verso sinistra. I numeri binari vengono costruiti nello stesso modo solo che invece di potenze di 10 si usano le potenze di 2, quindi considerando il seguente numero binario, scomponendolo ed effettuando i calcoli si ottiene il corrispondente numero decimale :

11010010 = 1*2^7 + 1*2^6 + 0*2^5 + 1*2^4 + 0*2^3 + 0*2^2 + 1*2^1 + 0*2^0 = 210

Ora che abbiamo visto la conversione Base 10 -> Base 2 vediamo come si effettua l'operazione inversa.
L'algoritmo è abbastanza semplice :

1 - Si divide la cifra decimale per 2
2 - Se il quoziente è intero si scrive 0 se non è intero 1
3 - Si divide il quoziente ancora per 2 e si ripete il passo 3
4 - La sequenza ottenuta RIBALTATA è la rappresentazione binaria del numero decimale

Vediamolo applicato al numero decimale 145 (questo è lo schema che di solito si utilizza):

                       
                             145 | 
                              72 | 1	( cifra - significativa )
                              36 | 0
                              18 | 0
                               9 | 0
                               4 | 1
                               2 | 0
                               1 | 0
                               0 | 1     (cifra + significativa )

Quindi 145 in base 10 equivale a 10010001 in base 2. Semplice vero ??
NOTA: Una cosa da notare è che con N cifre binarie possiamo rappresentare tutti i numeri da 0 fino a 2^N-1.

Ora che abbiamo conosciuto i numeri in base 2 andiamo a conoscere i numeri in base 16 che risultano utili in quanto ogni cifra esadecimale corrisponde a 4 cifre binarie e il passaggio da una base all'altra risulta facile.
Tanto per cominciare le cifre del Sistema esadecimale sono 16, direte 10 le conosciamo ma le altre 6 ?? Beh si usano anche le prime sei lettere dell'alfabeto :

     DEC    0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  
     HEX    0  1  2  3  4  5  6  7  8  9   A   B   C   D   E   F   


Anche il sistema esadecimale è posizionale e quindi la conversione Hex ->Dec si fa nello stesso modo visto prima ( naturalmente si usano le potenze di 16).
Un'altra conversione che serve spesso è quella da Esadecimale a Binario e viceversa.
Sono entrambe molto semplici in quanto come dicevamo prima tutte le cifre esadecimali si possono codificare con quattro cifre binarie :

                                Hex             Bin
                                 0              0000
                                 1              0001
                                 2              0010
                                 3              0011
                                 4              0100
                                 5              0101
                                 6              0110
                                 7              0111
                                 8              1000
                                 9              1001
                                 A              1010
                                 B              1011
                                 C              1100
                                 D              1101
                                 E              1110
                                 F              1111


Quindi il numero esadecimale 3F5 corrisponde al
    001111110101                                                                                
     3   F   5
Per il viceversa basta prendere il numero binario a blocchi di 4 cifre (partendo dalla cifra meno significativa) e convertirli in cifre esadecimali:

10 0101 1101 0101 0010

        0010 --> 2
        0101 --> 5
        1101 --> D
        0101 --> 5
          10 --> 2
Quindi corrisponderà al numero 25D52 esadecimale !!
Un altro sistema di numerazione adottato nel campo dei calcolatori fino a qualche tempo fa era quello ottale (base 8), che lascio immaginare a voi come funzioni !!
In un programma assembly per specificare la base di numerazione si fa seguire al numero una lettera :

b - Binario (es. 0100101101b)
o - Ottale (es. 543o)
d - Decimale (es. 982d)
h - Esadecimale (es. 0F23h)

Adesso siamo in grado di rappresentare solo i numeri positivi e quelli negativi?
Per questi i calcolatori utilizzano un metodo non sempre intuitivo: il complemento a 2.
Vediamo subito un esempio per capire come funziona, consideriamo il numero 5 e rappresentiamolo in binario a 8 bit : 00000101, calcoliamo da questo la rappresentazione binaria di -5, si procede nel seguente modo :

1 - Si complementano tutti  i bit (0-->1 e 1-->0)

                00000101
                ||||||||
                11111010 

2 - al numero ottenuto si somma 1

                11111010 +
                       1
               ----------
                11111011

3 - Il numero ottenuto è la rappresentazione binaria di -5
Per fare la verifica provate a sommare 5 a -5 e vedrete che otterrete 0
(attenzione : il bit eventuale di overflow viene perso in quanto nel nostro esempio abbiamo specificato che stiamo usando solo 8 bit; anche in un calcolatore comunque il numero di bit è limitato dalla dimensione dei registri) Quindi con n bit possiamo rappresentare i numeri da -2^(n-1) a 2^(n-1)-1 (es. con 4 bit da   -8 a 7) e il bit più significativo indica il segno : se è 1 vuol dire che il numero è negativo.

Oltre al codice binario normale a volte sono utili altre rappresentazioni binarie dei numeri decimali (utili come vedremo più avanti per le operazioni algebriche) come ad esempio la notazione BCD (Binary Coded Decimals). In BCD le 10 cifre del codice decimale vengono codificate una ad una con 4 bit nel seguente modo:

        Decimale  0    1    2    3    4    5    6    7    8    9   
           BCD   0000 0001 0010 0011 0100 0101 0110 0111 1000 1001


Così per rappresentare il numero decimale 145 basta codificare le sue cifre (1,4 e 5) con il rispettivo codice BCD :

145 --> 101000101

L'Assembly non è un linguaggio tipizzato, nel senso che non esiste il tipo int, float, ecc... sta al programmatore trattare i numeri in modo diverso a seconda di cosa essi rappresentano nel momento in cui li usa.
In binario vengono rappresentati anche i caratteri. Per ogni carattere si usano 8 bit, per un totale di 256 caratteri, per le corrispondenze carattere-codice si fa riferimento alla convenzione ASCII. Tutti abbiamo da qualche parte una tabella dei codici ASCII.


Oltre a saper rappresentare i numeri binari bisogna saper fare anche le operazioni con essi, spendero' solo poche parole ma una volta capito il meccanismo di base riuscirete benissimo a risolvere complesse operazioni !!!.
Per capire come si effettua una somma basta pensare a cosa avviene con i numeri in base 10 e ricordarsi che in base 2 ci sono solo due cifre.
Quindi (in base 10) se sommo 7 a 6 scrivo 3 con il riporto di 1, sommo il riporto a 0 e unendo i risultati ottengo (magia) 13.
In decimale il riporto si ha quando la somma supera 10-1=9 in binario quando la somma supera 2-1=1, quindi ad esempio :

                10100011 +
                10100101
               ----------
               101001000
Provate a fare qualche esempio vedrete che è facilissimo, l'importante è aver capito il meccanismo che sta alla base che è analogo a quello che si usa in decimale.

Ora che abbiamo capito come fanno a "contare" i computer vediamo come fanno a fare altre utili operazioni, guardiamo in particolare le operazioni logiche. La logica è un ramo della matematica che stabilisce se un predicato è vero o falso (chiedo scusa ai matematici per la definizione un po'troppo semplicistica), quindi noi assegneremo il valore 1 a vero e il valore 0 a falso e il gioco è fatto.
Le principali sono: AND, OR, NOT, XOR.
Noi ci chiederemo cosa risulta 1 and 1 oppure 0 or 1 ecc...
Per brevità e data la semplicità riporto solo le tabelle di verità di queste operazioni logiche, in ingresso avremo una o due variabili binarie X e Y e in uscita verrà prodotta la variabile Z che varrà 0 o 1 a seconda dell'operazione logica; quindi:

  AND   X  Y  | Z
        0  0  | 0
        0  1  | 0               Z = X and Y
        1  0  | 0
        1  1  | 1


  OR    X  Y  | Z
        0  0  | 0
        0  1  | 1               Z = X or Y
        1  0  | 1
        1  1  | 1


  XOR   X  Y  | Z
        0  0  | 0
        0  1  | 1               Z = X xor Y             ( or esclusivo )
        1  0  | 1
        1  1  | 0

  NOT       X | Z        
            0 | 1    Z= not X    ( il NOT a differenza degli altri è un  
            1 | 0                  operatore unario: opera su una sola  
                                   variabile)
		
Questo è quello che si chiama condensato di logica però è tutto quello che ci serve sapere sulle operazioni, se volete approfondire il concetto contattatemi e sarò lieto di darvi altre informazioni su questo campo della matematica 8-)

Beh ora penso di avervi stufato abbastanza con tutta questa matematica ma ritengo che una buona comprensione di questi argomenti faciliti molto la comprensione di quello che faremo in futuro, infatti con il linguaggio Assembly si lavora principalmente con numeri esadecimali, quindi resistete e fate un po' di esempi per capire se avete capito.



Assembly Page di Antonio
<< Indice >>