Il est indispensable
de bien comprendre cette section. En effet, le système décimal
que nous utilisons tous les jours n'est pas forcément le
plus simple pour programmer en asm. En effet, le microprocesseur
ne connaît et ne traite que le binaire, et nous allons voir
que pour simplifier les choses on peut utiliser l'hexadécimal.
Le binaire
Vous savez très
certainement qu'un ordinateur code toutes les informations essentiellement
avec des 0 et des 1. Donc, les nombres aussi. C'est-à-dire
que le système binaire est utilisé pour représenter
et traiter les nombres. En décimal, nous comptons à
partir de 0, puis on ajoute 1 à chaque fois, jusqu'à
atteindre le dixième chiffre, 9. A partir de là, on
rajoute un "1" devant et on recommence... En binaire,
c'est pareil mais avec seulement deux chiffres (les 0 et les 1 ne
sont plus appelés "chiffres", mais "bits").
On obtient donc la table de correspondance suivante :
Décimal
|
Binaire
|
0
|
0b
|
1
|
1b
|
2
|
10b
|
3
|
11b
|
4
|
100b
|
5
|
101b
|
6
|
110b
|
7
|
111b
|
|
Remarque
: pour différencier les nombres binaires des nombres
décimaux, on fait suivre les nombres binaires d'un "b".
On laisse les nombres décimaux comme ils le sont, bien
que certains préfèrent les faire suivre d'un "d".
C'est vous qui voyez... |
Avec 3 bits,
on peut représenter 2^3 (2 puissance 3) = 8 valeurs différentes
: de 0 à 7.
Nous verrons dans les sections suivantes que le microprocesseur
travaille avec des nombres d'au moins 8 bits (8 bits = 1 octet).
Avec 8 bits, on peut donc représenter 2^8=256 valeurs différentes
: de 0 à 255.
Comme vous
pouvez l'imaginer, on arrive très vite à des nombres
comportants des dizaines de bits... Pour convertir en décimal,
il existe une méthode très simple : compter les puissances
de 2. Pour cela, on attribue à chaque bit un index de position,
en partant du bit le moins significatif (le bit de droite). Le nombre
en décimal est égal à la somme des 2^n, n correspondant
aux index des "1". Exemple pour le nombre binaire 10011011b
codé sur 8 bits :
Index
|
7
|
6
|
5
|
4
|
3
|
2
|
1
|
0
|
Bits
|
1
|
0
|
0
|
1
|
1
|
0
|
1
|
1
|
En décimal,
cela donne donc :
2^7+2^4+2^3+2^1+2^0
= 128+16+8+2+1 = 155
Mais il y
a plus simple : utiliser une calculatrice, les TI et les Casio par
exemple le font très bien (ça dépend des modèles).
Si vous n'en possédez pas, sachez que la calculatrice de
Windows le fait (affichage scientifique) !
Quant à
la conversion décimal => binaire, il vous suffit de décomposer
le nombre en puissances de 2 et d'en déduire les positions
des "1".
Pour représenter
les nombres négatifs, la méthode est un petit peu
plus complexe. Pour rendre un nombre négatif, on commence
par le complémenter (c'est-à-dire inverser tous ses
bits). On obtient alors le "complément-à-1",
ou plus simplement "complément". Puis on ajoute
1, on a alors le "complément-à-2", qui représente
le négatif du nombre. Par exemple, prenons le nombre 70 codé
sur 8 bits : 01000110b. On le complémente-à-2, c'est-à-dire
on inverse tous ses bits : 10111001b, puis on lui ajoute 1 : 11011010b.
Ce nombre est donc -70 en binaire.
ATTENTION
: Lors du compément-à-1, il faut absolument inverser
TOUS les bits. Par exemple, le même nombre -70, codé
sur 16 bits cette fois, donnera 1111111110111010b.
Remarque :
Bien sûr, si on complémente-à-2 deux fois un
nombre, le résultat reste inchangé.
Mais vous
allez me dire, si on applique la méthode de conversion précédente,
on trouve que 10111010b = 2^7+2^5+2^4+2^3+2^1 = 128+32+16+8+2 =
186 ! En fait, tout dépend de comment vous considérez
votre nombre. Si vous décidez qu'il est signé, alors
il sera égal à -70, et avec 8 bits vous pourrez représenter
des nombres de -128 à 127. Si vous le considérez comme
non-signé, il sera égal à 186, et avec 8 bits
vous pourrez représenter des nombres de 0 à 256. L'avantage
de considérer les nombres comme non-signés, est donc
qu'avec le même nombre de bits, on peut représenter
plus de valeurs positives, donc si vous savez qu'une variable ne
peut pas prendre des valeurs négatives, n'hésitez
pas.
ATTENTION
: Un nombre signé n'est pas forcément négatif,
cela signifie simplement qu'il possède un signe : positif
ou négatif. Par contre un nombre non-signé est forcément
positif.
Une question
que se posent beaucoup de débutants : pourquoi n'a t'on pas
inventé une méthode plus simple pour représenter
les nombres négatifs, par exemple le bit le plus à
gauche pourrait représenter le signe : 0 pour positif et
1 pour négatif ? En fait, personne n'a établit de
règle, c'est tout simplement le résultat que l'on
trouve en faisant une soustraction de zéro. Exemple : -70
peut s'écrire 0-70. 70 en binaire est 01000110b. On effectue
donc la soustraction, en prenant garde aux retenues (c'est comme
en décimal).
L'énorme
avantage de cette convention est que le microprocesseur n'a pas
besoin de savoir si les nombres sont signés ou non-signés
pour effectuer les additions et les soustractions, le résultat
est bon dans les deux cas. Par contre, pour une multiplication ou
une division, il faudra l'indiquer au microprocesseur, car si les
nombres sont signés, le résultat sera négatif
si les deux nombres n'ont pas le même signe.
L'hexadécimal
L'hexadécimal
(base 16), contrairement à ce que pourraient penser certains,
est utilisé pour simplifier les choses. En effet, il permet
non seulement d'écrire de gros nombres en peu de chiffres
(en fait en hexadécimal on parle de "digits"),
mais surtout il est facilement convertible en binaire, pour la bonne
et simple raison que chaque digit peut être remplacé
par 4 bits.
On a donc
16 digits pour coder les nombres : 0,1,....,9 puis A,B,C,D,E,F !
Pour différencier les nombres en hexa des nombres en décimal,
on rajoute un "h", par exemple "6h". En notation
langage C, on les fait précéder de "0x".
Ces deux notations sont acceptées par l'assembleur.
Voici la table
de correspondance complète :
Décimal
|
Hexadécimal
|
Binaire
|
0
|
0
|
0000
|
1
|
1
|
0001
|
2
|
2
|
0010
|
3
|
3
|
0011
|
4
|
4
|
0100
|
5
|
5
|
0101
|
6
|
6
|
0110
|
7
|
7
|
0111
|
8
|
8
|
1000
|
9
|
9
|
1001
|
10
|
A
|
1010
|
11
|
B
|
1011
|
12
|
C
|
1100
|
13
|
D
|
1101
|
14
|
E
|
1110
|
15
|
F
|
1111
|
Avec cette
table, vous pouvez passer très rapidement de binaire à
hexadécimal et d'hexadécimal à binaire, il
n'y a qu'à remplacer. Exemple : B8h=10111000b. 01001110b=4Eh.
Remarque : Si vous utilisez la notation
"h" plutôt que "0x", alors il faudra penser
à rajouter "0" (le nombre, pas la lettre) devant
les nombres hexadécimaux qui commencent par une lettre, sinon
l'assembleur va confondre avec un nom de variable. B8h devra donc
être écrit 0B8h.
Mais je préfère
vous faire découvrir par la pratique l'intérêt
de l'hexadécimal. Nous nous en servirons donc dans les sections
suivantes, lorsqu'on en aura besoin.

|
Copyright 2000 Jean-Rémy Lacharnay.
Je ne pourrais être tenu pour responsable des éventuelles conséquences
que l'exécution des exemples fournis peut avoir sur votre machine (plantages,
pertes de données, etc...).
|
|
|