II Les bases

1. Les systèmes de numérotation

 

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...).