Binario ed esadecimale

Prima di passare al codice dobbiamo introdurre alcuni concetti.

Quando si programma ad un basso livello è fondamentale capire bene i sistemi binario ed esadecimale. Se già conoscessi questi concetti, in fondo alla pagina ci sono delle informazioni specifiche all’uso di RGDBS.

Cos’è il binario? È semplicemente un modo alternativo di rappresentare i numeri, in base 2. Noi contiamo in base 10, ovvero con 10 cifre: 0, 1, 2, 3, 4, 5, 6, 7, 8, e 9. Le cifre hanno una funzione ben specifica:

  42 =                       4 × 10   + 2
     =                       4 × 10^1 + 2 × 10^0
                                  ↑          ↑
    These tens come from us counting in base 10!

1024 = 1 × 1000 + 0 × 100  + 2 × 10   + 4
     = 1 × 10^3 + 0 × 10^2 + 2 × 10^1 + 4 × 10^0
       ↑          ↑          ↑          ↑
And here we can see the digits that make up the number!

CONVENTION

^ qui significa “alla potenza di”, dove X^N è uguale a moltiplicare X con se stesso N volte, e X ^ 0 = 1.

Con le cifre decimali ogni numero viene scomposto in maniera univoca in potenze di 10 (il decimale è la base 10, ricordi?). Ma perché fermarsi alle potenze di 10? Potremmo invece usare altre basi, come la base 2 (il perché della base 2 sarà spiegato più avanti).

Il sistema binario è in base 2, quindi ha solo due cifre (chiamate bit): 0 e 1. Possiamo quindi generalizzare il principio descritto sopra e riscrivere i due numeri di prima in modo simile:

  42 =                                                    1 × 32  + 0 × 16  + 1 × 8   + 0 × 4   + 1 × 2   + 0
     =                                                    1 × 2^5 + 0 × 2^4 + 1 × 2^3 + 0 × 2^2 + 1 × 2^1 + 0 × 2^0
                                                              ↑         ↑         ↑         ↑         ↑         ↑
                                          And since now we're counting in base 2, we're seeing twos instead of tens!

1024 = 1 × 1024 + 0 × 512 + 0 × 256 + 0 × 128 + 0 × 64  + 0 × 32  + 0 × 16  + 0 × 8   + 0 × 4   + 0 × 2   + 0
     = 1 × 2^10 + 0 × 2^9 + 0 × 2^8 + 0 × 2^7 + 0 × 2^6 + 0 × 2^5 + 0 × 2^4 + 0 × 2^3 + 0 × 2^2 + 0 × 2^1 + 0 × 2^0
       ↑          ↑         ↑         ↑         ↑         ↑         ↑         ↑         ↑         ↑         ↑

Quindi, applicando lo stesso principio, possiamo dire che in base 2, 42 si scrive come 101010 e 1024 come 10000000000. Poiché non è possibile distinguere tra dieci (10 decimale) e due (10 binario), l’assemblaggio RGBDS prevede numeri binari preceduti da un segno di percentuale: 10 è dieci e %10 è due.

Ok, ma perché proprio la base 2? Visto che un bit può essere solo 0 o 1, è molto facile rappresentarlo: può essere “ON” o “OFF”, vuoto o pieno, ecc! Se ad esempio si vuole creare una memoria da un bit basta prendere una scatola: se è vuota allora simboleggia uno 0; se contiene qualcosa, allora è un 1. I computer manipolano quindi principalmente numeri binari e questo ha molte implicazioni, come vedremo nel corso di questo tutorial.

Esadecimale

Ricapitolando: il decimale non è pratico per i computer, che si affidano invece ai numeri binari (base 2). Ok, ma il binario è davvero difficile da usare per noi programmatori. Prendiamo %10000000000, ovvero 2048; mentre per scriverlo in decimale bastano solo 4 cifre, in binario ne servono 12! E probabilmente non avete neanche notato che ho scritto uno zero di troppo! Per fortuna arriva l’esadecimale a salvare la situazione! 🦸

La base 16 funziona esattamente come tutte le altre basi, ma con 16 cifre (chiamate “nibbles” in inglese): 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, ed F.

  42 =            2 × 16   + 10
     =            2 × 16^1 + A × 16^0

1024 = 4 × 256  + 0 × 16   + 0
     = 4 × 16^2 + 0 × 16^1 + 0 × 16^0

Come per il binario useremo un prefisso per indicare l’esadecimale, cioè $. Quindi, 42 = $2A e 1024 = $400. Questo è molto più compatto del binario, e anche un po’ più del decimale; ma ciò che rende l’esadecimale molto interessante è che una sua cifra corrisponde esattamente a 4 bit!

NibbleBits
$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

Ciò rende facilissimo convertire tra binario ed esadecimale, e mantenere una notazione sufficientemente compatta. Per questo, l’esadecimale è molto più utilizzato del binario. E non preoccuparti, puoi ancora usare il decimale 😜

(Nota: si potrebbe pensare che anche l’ottale, cioè la base 8, funzioni altrettanto bene; tuttavia avremo a che fare perlopiù con unità di 8 bit, per le quali l’esadecimale funziona molto meglio dell’ottale. Volendo, RGBDS permette di usare l’ottale tramite il prefisso &, ma non l’ho mai visto usare nella pratica)

If you’re having trouble converting between decimal and binary/hexadecimal, check whether your favorite calculator program has a ‘programmer’ mode or a way to convert between bases.

  • In RGBDS assembly, the hexadecimal prefix is $, and the binary prefix is %.
  • Hexadecimal can be used as a “compact binary” notation.
  • Using binary or hexadecimal is useful when individual bits matter; otherwise, decimal works just as well.
  • For when numbers get a bit too long, RGBASM allows underscores between digits (123_465, %10_1010, $DE_AD_BE_EF, etc.)