CODINGDEMONIAK ★ COURS d'ASSEMBLEUR par DEMONIAK ★

Cours d'assembleur par Demoniak - Partie 1 : Les bases de nombresCoding Demoniak

Partie 1 : Les bases de nombres

On sait tous compter jusqu'à dix, cent, mille, dix mille... et même jusqu'à plusieurs millions...
Mais pour ce petit cours, on s'arrêtera à a peu près soixante cinq mille et des poussières. Nous verrons pourquoi ultérieurement...

Pour comprendre ce qui va suivre, il faut faire la distinction entre les nombres et les chiffres.
En gros, les nombres sont infinis, un million est un nombre. Par contre, les chiffres sont une méthode de représentation des nombres. Nous décrivons les nombres avec dix chiffres, qui vont de 0 à 9. (Pour faire le rapport avec l'alphabet, nous décrivons les mots avec vingt six lettres, de A à Z.) Lorsque nous avons atteint 9, pour décrire le nombre suivant, il suffit d'ajouter le chiffre 1 et le chiffre 0, ce qui donne dix. Cette méthode de représentation des nombres n'est pas unique.

En fait, nous représentons les nombres en base dix. Pourquoi base dix ? Parce que nous utilisons 10 chiffres. Maintenant, imaginons qu'il n'y a que deux chiffres possibles, le 0 et le 1. Dans ce cas, on dit que l'on est en base deux, car seuls deux chiffres existent.

Pour compter jusqu'à un, pas de problèmes, 0 puis 1. et maintenant le nombre deux ? Et bien, comme nous n'avons plus de chiffres disponibles, on va faire comme on faisait en base dix, on ajoute un chiffre devant et on recommence, ainsi, notre deux va se représenter 10.

Et trois ? Et bien trois en base deux se représente 11. En fait, on augmente le chiffre le plus à droite. Lorsque celui-ci a atteint son maximum, il repasse à zéro (le premier chiffre de toutes les bases est le zéro) et on augmente le chiffre suivant à gauche. Si ce dernier a également atteint lui aussi son maximum, on répète l'opération : on le repasse a zéro et le chiffre le plus à gauche est augmenté, et ainsi de suite.

Voici donc un exemple de représentation des seize premiers nombres en base deux :

Zéro
0
un
1
deux
10
trois
11
quatre
100
cinq
101
six
110
sept
111
huit
1000
neuf
1001
dix
1010
onze
1011
douze
1100
treize
1101
quatorze
1110
quinze
1111

J'ai volontairement aligné les valeurs en base deux à droite, ce qui permet de bien voir que le chiffre le plus à droite est toujours augmenté, ensuite c'est le chiffre suivant à gauche, et ainsi de suite. Je me suis également volontairement arrêté à quinze, nous verrons pourquoi plus tard.
Mais sachez quand même que le seize se représente ainsi : 10000 (cinq chiffres !)

Quelques termes à savoir : la base dix est appelée base décimale, ou plus couramment le décimal. La base deux est appelée base binaire, mais plus couramment le binaire.
Un groupement de 8 bits et appelé octet (en référence à octal, qui signifie 8). Mais à quoi ça peut bien servir de compter en binaire ? Et bien en fait, le microprocesseur Z80 (et tous les microprocesseurs) ne savent compter qu'en binaire. Et pourquoi qu'ils ne savent compter qu'en binaire les microprocesseurs ? Parce que les informations qu'ils traitent sont représentées sous forme de tensions électriques, et en gros, ils ne savent distinguer que deux sortes d'informations : une tension est présente, ou il n'y a pas de tensions présentes.

En gros, on peut comparer un microprocesseur à une ampoule, et l'information qu'il a à traiter à l'interrupteur qui commande l'ampoule. Quand on actionne l'interrupteur, l'ampoule s'allume. Quand on actionne l'interrupteur dans l'autre sens, l'ampoule s'éteint. L'ampoule travaille donc en binaire, elle ne connait que deux états, éteinte, que l'on peut faire correspondre à l'état zéro, et allumée, que l'on peut faire correspondre à l'état un.

Et voilà que nous avons crée notre premier programme en language machine : l'allumage de l'ampoule !
Plus sérieusement, c'est l'un des principes primordiaux des microprocesseurs, le traitement des informations en binaire.

Mais comment ils font pour traiter des grands nombres, les microprocesseurs ? Et bien, comme nous l'avons fait tout à l'heure dans notre exemple pour compter jusqu'à quinze en binaire, ils ajoutent des chiffres.

Et c'est là qu'intervient la notion de 'bit'. Quoi ? Qu'est ce que c'est que ça ? Me direz-vous... Plutôt que de parler de chiffres, qui eux vont de zéro à neuf, on parle de bits pour la représentation des nombres en binaire.

Donc, pour résumer, un bit est un élément qui prends la valeur 0 ou 1, et qui sert, lorsque l'on en associe plusieurs, à représenter des nombres en binaire. Et notre bon vieux Z80 étant un microprocesseur huit bits, cela signifie qu'il est capable de traiter des nombres représentés par un regroupement de huit bits.

Mais ça va jusqu'à combien, un nombre de huit bits ? Plutôt que d'essayer d'écrire toutes les combinaisons possibles des huit bits pour arriver au maximum (qui sera représenté par 11111111), il existe des formules mathématiques simples pour connaître le nombre maximal représenté par un groupement de chiffres dans une certaine base. Si nous revenons en décimal, il est facile de savoir que l'on représente les nombres de zéro à neuf avec un chiffre (soit dix nombres différents), de zéro à quatre vingt dix neuf avec deux chiffres (soit cent nombres différents) et ainsi de suite. La formule mathématique pour le décimal est : 10 puissance nombre_de_chiffres.

Par exemple, si nous utilisons quatre chiffres, on peut représenter : 10 puissance 4 = dix mille nombres, de zéro à neuf mille neuf cent quatre vingt dix neuf.
Et la formule est générale à toutes les bases, soit :
base puissance nombre_de_chiffres.

Pour notre Z80, nous travaillons en binaire avec 8 chiffres (pardon bits), la formule nous donne : 2 puissance 8 = deux cent cinquante six valeurs, de zéro à deux cent cinquante cinq.
Mais j'ai entendu dire que le Z80 pouvait traiter des nombres de 16 bits ? Et bien oui, il peut traiter des nombres de 16 bits, mais ça, nous le verrons plus tard.

On peut juste remarquer qu'un nombre de 16 bits aura une valeur maximale de... (Sortez les calculettes...) de 2 puissance 16 = 65536, soit de 0 à 65535, et que la représentation en binaire de sa valeur maximale (65535 donc) est : 1111111111111111 (soit seize 1). Pas très pratique comme représentation, n'est ce pas ? Heureusement, il y a un autre moyen de représenter des nombres que le binaire: l'hexadécimal.

Qu'est ce que c'est encore que ce terme barbare ?

L'hexadécimal est en fait le nom couramment employé pour la base 16. La base 16 est donc une base de comptage qui comporte 16 chiffres. les chiffres sont donc 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,... Et après ? Et bien, comme nous n'avons plus de chiffres, symboliquement parlant, pour continuer, on va piocher dans les lettres pour les six symboles qui nous manque, c'est à dire A, B, C, D, E, F.
Ouf ! Pour résumer, la base 16 utilise 16 chiffres qui sont (dans l'ordre) : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.

Si nous revenons à notre petit exemple du début, pour représenter les seize premier nombres en base 16 (hexadécimal), nous écrirons :

décimal
hexadécimal
zéro
0
un
1
deux
2
trois
3
quatre
4
cinq
5
six
6
sept
7
huit
8
neuf
9 (jusqu'ici, pas de problèmes)
dix
A (c'est ici que l'on ajoute les caractères
onze
B qui nous manquait en base 10...)
douze
C
treize
D
quatorze
E
quinze
F

Et le seize alors ? Et bien, comme pour toutes les bases, on représente le seize ainsi : 10 (avec le F du quinze, on repasse a zéro et on augmente le chiffre immédiatement à gauche).

Si l'on étend cet exemple plus loin, et que l'on fait l'analogie avec les nombres en binaire, on remarque qu'il y a une relation directe entre le binaire et l'hexadécimal : un groupe de 4 bits sera toujours représenté de la même façon en hexadécimal.

En plus, comme 4 bits peuvent représenter un maximum de 16 nombres, c'est exactement ce que peuvent représenter un chiffre hexadécimal !

Voici un exemple :

Décimal
Binaire
Hexadécimal
0
0
0
1
1
1
2
10
2
3
11
3
4
100
4
5
101
5
6
110
6
7
111
7
8
1000
8
9
1001
9
10
1010
A
11
1011
B
12
1100
C
13
1101
D
14
1110
E
15
1111
F
16
10000
10
20
10100
14
26
11010
1A
74
1001010
4A
170
10101010
AA

Maintenant, pour plus de lisibilité, on ajoute à gauche les zéros non significatifs, et on sépare en groupe de 4 bits (ou un chiffre hexa...)

Décimal
Binaire
Hexadécimal
000
0000 0000
0 0
001
0000 0001
0 1
002
0000 0010
0 2
03
0000 0011
0 3
004
0000 0100
0 4
005
0000 0101
0 5
006
0000 0110
0 6
007
0000 0111
0 7
008
0000 1000
0 8
09
0000 1001
0 9
010
0000 1010
0 A

On remarque donc une forte analogie entre l'hexadécimal et le binaire. Il est donc facile de faire des conversion hexadécimalbinaire. Ce qui semble plus compliqué que les conversions décimalbinaire.

Allez, un petit exemple :
convertir :

11011001 (binaire) en hexadécimal ...

Bon, 1101, ca fait D en hexa et 1001 9, donc dans notre exemple, 11011001 fait D9 en hexa !

Un autre ? ok, convertissons : 11110011 (binaire) en hexadécimal... 1111 = F, 0011 = 3, soit F3 !

Une remarque importante, les codes hexadécimal (on préfère parler de codes que de chiffres, car ces 'codes'mélangent chiffres et lettres) peuvent être confondus avec du texte. C'est pourquoi, généralement, on ajoute un symbole devant un nombre hexadécimal, pour indiquer qu'il s'agit bien d'un nombre, et non d'un nom quelconque !

Ce symbole est en général le dièse (#) ou le 'et' commercial (&). Donc, nos deux nombres hexa des exemples précédents se représentent ainsi : #D9 ou &D9 et #F3 ou &F3.
Pour le binaire aussi, on utilise un caractère qui permet de faire la différence entre un nombre binaire et un nombre décimal. Ce caractère est en général le pour-cent (%). On note donc %11011001 et %11110011.

Pas trop compliqué pour l'instant ? Ok, on va corser un peu...

Comment faire les conversions binairedécimal ?

Pour convertir un valeur binaire en décimal, c'est assez simple. En fait, comme chaque chiffres binaire ne peut avoir que la valeur 0 ou 1, il suffit de donner un poids à chaque bit de notre nombre binaire. Ce poids sera de plus en plus fort au fur et à mesure que l'on va se déplacer dans les chiffres vers la gauche.

Ainsi, le poids du chiffre le plus à droite est égal à 1, le poids du chiffre immédiatement à sa gauche 2, puis 4, puis 8, puis 16... En fait, il suffit de reprendre les puissances de deux (puisque l'on est en base deux) pour affecter le poids de chaque bits.
Ce qui nous donne :

Numéro du bit 7 6 5 4 3 2 1 0
Poids 128 64 32 16 8 4 2 1

On numérote les bits en général en commençant à zéro pour le bit le plus à droite, car on remarque que deux puissance zéro = 1 (poids) et ainsi de suite... (deux puissance 7 = 128)

Le bit le plus à droite est aussi appelé bit de poids faible. Le bit le plus à gauche est quand à lui appelé bit de poids fort (car c'est lui qui a le plus gros poids...) Prenons un exemple, avec le nombre binaire %10110010.

Numéro du bit 7 6 5 4 3 2 1 0
Poids 128 64 32 16 8 4 2 1
Valeur du bit 1 0 1 1 0 0 1 0

Et là, il suffit d'additionner les poids des bits non nuls, à savoir :
128 + 32 + 16 + 2, ce qui nous donne 178 en décimal !
Facile ? Bon, essayons le sens inverse...
Prenons un autre nombre, par exemple 201 en décimal. Comment convertir 201 en binaire ? C'est à peine plus compliqué. Il suffit de décomposer 201 dans ses puissances de deux, soit les poids d'un nombre binaire.
On remarque que 201 est plus grand que 128, donc, le bit 7 (celui qui a le poids 128) est à 1. Puis, on soustrait 128 à notre nombre, soit 201-128=73. On recommence ainsi pour toutes les puissances de deux, soit jusqu' à 1 (2 puissance 0)
Bon, reprenons depuis le début :

201 - 128 = 73 ( 201 contient 128, bit à 1 )
73 - 64 = 9 ( 73 contient 64, bit à 1 )
9 - 32 < 0 ( 9 ne contient pas 32, bit à 0 )
9 - 16 < 0 ( 9 ne contient pas 16, bit à 0 )
9 - 8 = 1 ( 9 contient 8, bit à 1 )
1 - 4 < 0 ( 1 ne contient pas 4, bit à 0 )
1 - 2 < 0 ( 1 ne contient pas 2, bit à 0 )
1 - 1 = 1 ( 1 contient 1, bit à 1 )

Voila, simple non ? Bon, oui, un peut complexe, mais en s'entraînant, ça devient vite facile, on retient les puissances de deux, et certaines conversions deviennent implicites. Pour la conversion décimalhexadécimal, c'est un peu plus compliqué, et je vous conseille de passer d'abord par une conversion décimalbinaire, puis une conversion binairehexadécimal, très facile.

Maintenant que l'on sait comment le microprocesseur représente les nombres (en binaire), comment il fait pour calculer ?

Et bien, le plus simplement du monde...
Quand nous faisons une addition sur papier, nous procédons ainsi : (addition en décimal)

45
+87
-----
=132
Pour arriver à cela, nous faisons : 5+7 = 12 (je pose 2 et je retiens 1), 4+8+1 (notre retenue)=13, soit 132.

En binaire, c'est pareil, on a une retenue dès que l'on dépasse le plus grand chiffre possible soit 1.

Exemple :

%01001010
+%10111010
----------
%100000100

Si on décompose l'addition, on part de la droite vers la gauche.

— Les deux premier chiffres, 0+0 = 0, facile.
— Ensuite 1+1, en binaire, ca fait 10, on pose 0 et on retiens 1.
— Puis, 0+0=0 PLUS notre retenue, soit 1.
— Ensuite, 1+1 =0, retiens 1, 0+1=1 PLUS retenue = 0 retiens 1,
— Encore, 1+1 =0, retiens 1, 0+1=1 PLUS retenue = 0 retiens 1,
— Encore, 1+1 =0, retiens 1, 0+1=1 PLUS retenue = 0 retiens 1,
— 1+0 = 1 PLUS Retenue = 0, retiens 1
— 0+1 = 1 PLUS Retenue = 0, retiens 1
Et on ajoute notre retenue au final

Ouf !
Maintenant, le même en hexadécimal...
On reprends les mêmes chiffres,

#4A
+#BA
----
#104

Facile avec les conversion... Mais si nous faisons réellement l'addition, cela donne :
A+A = (dix + dix=vingt, soit #14), on pose 4 et on retiens 1.
4+B = (quatre + onze + RETENUE = seize, = #10), on pose 0 et retiens 1.
Et on pose enfin notre retenue, soit #104.

Maintenant que nous savons faire quelques calculs en binaire et en hexa, voyons comment gérer les nombres signés.

Oui, pour le moment, nous n'avons vu que des nombres positifs. Mais comment gérer les nombres négatifs ?

En rajoutant le symbole '-' me direz-vous. Oui... Mais bon, n'oublions pas que nous allons travailler avec un microprocesseur, qui gère des nombres de 8 ou 16 bits (nous verrons cela plus tard), et qui doit pouvoir connaître le signe d'un nombre avec un moyen simple. C'est pour cela que l'on a inventé les nombres signées et les nombres non signés.

Un nombre non signé, dison de 8 bits (un octet en fait), a sa valeur représenté par ces 8 bits. Un octet signé (un octet fait 8 bits), a sa valeur représenté par 7 bits seulement (les bits de poids le plus faible). Et le huitième bit ? Il sert de bit de signe.

Evidement, en supprimant un bit pour la valeur, on ne peut plus aller que de 0 à 127. Et avec le signe ?
Pour comprendre le fonctionnement du bit de signe, il faut revenir en binaire. Admetons que nous voulons décrire le nombre 54 (positif) en binaire. Voici comment il se décrit : %00110110, ou encore #36. Si nous travaillons en octets signé, le bit de poids le plus fort étant bien à zéro, nous avons bien là une valeur positive.

Pour représenter -54, il faut donc positionner le bit de signe à 1. On pourrai penser que c'est aussi simple que cela, et que -54 donne %10110110, ou encore #B6.
Mais non... -54 se décrit ainsi : %11001010 ou encore #CA.
Bon... Comment passer de 54 à -54 simplement ?
Et bien, on a inventé un codage, nomé "Complément vrai à 1" qui permet de représenter les nombres négatifs.

Pour cela, il suffit de complémenter (inverser) les bits de notre nombre, et ensuite de lui ajouter 1. Voici le détail :

54 : %00110110 #36
Complément : %11001001 #C9 (on inverse tous les bits)
Ajout 1 : +%00000001 #01
Résultat : %11001010 #CA

Pourquoi avoir ajouté 1 ? Et bien, dans le traitement des nombres positifs/négatifs, il y a un cas particulier à traiter.

Le cas du zéro. Le zéro étant considéré comme positif, il est absurde de vouloir le représenter avec un signe négatif. Donc, comme les nombres positifs varient de 0 à 127, les nombres négatifs ne varient pas de 0 à -127, mais de -1 à -128. D'ou l'ajout de 1 pour la conversion nombre positif->négatif.
Maintenant, faisons l'opération inverse : convertif -54 en +54...

-54 : %11001010 #CA
Complément : %00110101 #35 (on inverse tous les bits)
Ajout 1 : +%00000001 #01
Résultat : %00110110 #36

On retrouve donc bien notre 54 !
La méthode du complément vrai à 1 permet donc de passer de nombres positifs à négatifs, et inversement.
Elle fonctionne également pour les nombres de 16 bits, en utilisant le même principe, mais dans ce cas, c'est le bit 15 (bit de poids le plus fort) qui sert de signe.
Cette méthode permet de faire des soustractions très facilement : pour faire a - b, il suffit de faire a + (complément à 1 de b).

Bon, on s'arrête là pour Aujourd'hui... Ces bases sont importantes pour la suite, n'hésitez pas à faire quelques exemples de conversions, de calculs sur papier, et de contrôler vos résultat avec, par exemple, la calculatrice de Windows...

Page précédente : Cours et Initiation par Demoniak

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Cours d'assembleur par Demoniak - Partie 5 : Les instructions Z80 / Modes d'Adressage
» Coding » Cours d'assembleur par Demoniak - Partie 2: La mémoire
» Coding » Cours d'assembleur par Demoniak - Partie 6 : les vecteurs système
» Coding » Cours et Initiation par Demoniak
» Coding Src's » Dots (Demoniak)
» Coding » Cours d'assembleur par Demoniak - Partie 7 : les vecteurs système II
Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 793 millisecondes et consultée 3084 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.