Les
bases de l'assembleur
Les systèmes de numérotation
- Les opérateurs logiques
- Les constituants du PC
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
complé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.
Les opérateurs logiques
:
Encore de la théorie ! Désolé, mais on ne peut pas
connaître l'asm sans connaître les opérateurs logiques. Ne vous inquiétez pas,
ce n'est pas compliqué du tout ! Si vous savez programmer dans un autre langage,
alors vous les connaissez sûrement !
• L'opérateur AND (et)
En entrée, on lui donne deux bits. En sortie, il donne 1 si les
deux bits sont égaux à 1 et 0 si ce n'est pas le cas. Voici sa table de vérité
(sortie en fonction des entrées) :
Bit 1
|
Bit 2
|
AND
|
0
|
0
|
0
|
1
|
0
|
0
|
0
|
1
|
0
|
1
|
1
|
1
|
• L'opérateur OR (ou)
La sortie vaut 1 si au moins un des deux bits est égal à 1.
Table de vérité :
Bit 1
|
Bit 2
|
OR
|
0
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
1
|
1
|
• L'opérateur XOR (ou exclusif)
La sortie vaut 1 si un seul des deux bits est égal à
1.
Bit 1
|
Bit 2
|
XOR
|
0
|
0
|
0
|
1
|
0
|
1
|
0
|
1
|
1
|
1
|
1
|
0
|
• L'opérateur NOT (non)
C'est l'opérateur le plus simple : il inverse l'état de son
unique entrée.
• Technique du "masquage de bits"
Ces opérateurs sont *très* souvent utilisés en asm. Etant donné
que le microprocesseur ne peut pas manipuler directement les bits (on peut
seulement lire ou écrire 8, 16 ou 32 bits à la fois), on a recours à une
technique de "masquage". Par exemple, considérons que nous avons en mémoire une
variable. Nous voulons mettre à 1 son premier bit (le bit le plus à droite).
Pour cela, on utilise l'opérateur OR.
Avec cette méthode, le premier bit est mis
à 1, quel que soit son ancien état, et les autres bits restent inchangés
(regardez la table de vérité de la fonction OR : 0 OR 0 = 0, et 1 OR 0 =
1).
Si on voulait forcer le premier bit à 0,
alors il suffisait de faire un AND 11111110b.
On agit de manière similaire pour isoler un
bit afin de connaître sa valeur : pour savoir si le deuxième bit est égal à 1,
on fait un AND 00000010b, on place le résultat dans une mémoire intermédiaire,
et si cette mémoire est égale à 2 (2^1), alors cela veut dire que le deuxième
bit était égal à 1 ; dans le cas inverse il était égal à 0.
Les constituants du PC
• La mémoire
La mémoire est un ensemble de puces qui peuvent mémoriser une
quantité énorme de bits. On distingue deux types de mémoires : la mémoire ROM et
la mémoire RAM. ROM signifie Read Only Memory, c'est-à-dire qu'on ne peut que
la lire. Cette mémoire contient le BIOS (Basic Input/Output System), qui va se
charger à la mise sous tension du PC de son initialisation : détection des
périphériques installés tels que le disque dur, tests du matériel (processeur,
mémoire, ports, etc...), puis lancement du système d'exploitation. En outre, le
BIOS contient des routines systèmes pour accéder à l'écran, au clavier, à
l'heure et à la date, etc... que les programmes ou le système d'exploitation
peuvent appeler. RAM signifie Random Access Memory (mémoire à accès
aléatoire, ce qui veut dire qu'on peut lire/écrire à partir de n'importe quel
emplacement). Cette mémoire est réinitialisée à chaque démarrage du PC. La
mémoire est une suite de bits, cependant elle est organisée par octets,
c'est-à-dire par suites de 8 bits. Chaque octet de la mémoire possède une
"adresse". C'est par l'intermédiaire de cette adresse que l'on pourra lire ou
écrire un octet de mémoire. Plus concrètement, cela signifie que l'on ne peut
pas lire/écrire un seul bit directement, car toutes les opérations de
lecture/écriture se font à partir de l'adresse donnée, donc agissent sur au
moins un octet.
En mode 32 bits , la
limite théorique de la RAM est de 4 Go, car on utilise 32 bits pour représenter
les adresses, et 2^32 = 4294967296 octets, soit 4 Go (en effet vous devez savoir
que 1 Ko = 1024 octets, 1 Mo = 1024 Ko, etc...).
Vocabulaire : Une suite de deux octets forme un mot, une suite
de deux mots ou quatre octets forme un double-mot, ou long mot. En anglais,
cela donne : byte (octet), word (mot), double word (double mot) ou long word
(long mot).
• Le microprocesseur
C'est le cerveau du PC. Il est placé sur la carte mère. Son
unique rôle est d'exécuter des instructions machines qu'il va chercher dans la
mémoire. Ces instructions sont toutes codées par un nombre, appelé "opcode".
Voici ce que fait le microprocesseur : - Il va chercher dans la mémoire
l'opcode de l'instruction à exécuter. - En l'analysant, il prend connaissance
de l'instruction à exécuter, et aussi du nombre et de la taille des opérandes
(les opérandes sont les paramètres de l'instruction). - Il va chercher dans
la mémoire les opérandes. - Enfin il exécute l'instruction. - Puis il
recommence avec l'opcode suivant... La vitesse à laquelle sont effectuées ces
actions dépend évidemment de la fréquence du microprocesseur.
• Les contrôleurs
Les contrôleurs servent à gérer et à programmer tous les
périphériques externes et leur permettre de communiquer avec le microprocesseur.
Par exemple, il existe des contrôleurs de disque dur, de disquettes, de clavier,
d'écran (c'est la carte vidéo). Tous les périphériques ne possèdent pas de
contrôleurs : ainsi l'imprimante, la souris, le modem communiquent avec le
microprocesseur par l'intermédiaire des ports (série, parallèle, USB).
• Le bus
Il permet à tous ces composants de communiquer entre eux.
Ainsi, le microprocesseur accède à la mémoire à travers le bus. Mais sa
connaissance n'est pas nécessaire pour programmer en asm, car son utilisation
est tout à fait transparente. Sachez simplement qu'on peut y distinguer deux
voies : le bus d'adresses et le bus de données. Dans le bus d'adresses le
microprocesseur dépose l'adresse de l'octet en RAM désigné, et le bus de données
servira soit en envoyer l'octet à écrire, soit à recevoir le contenu de l'octet
visé.
La largeur du bus d'adresses définit la quantité maximale
d'octets disponibles. Sur le 386, elle est de 32 bits, donc la limite théorique
est de 4 Go, comme vu précédemment. La largeur du bus de données est liée
avec le nombre d'octets que l'on peut envoyer simultanément. Sur les anciens
ordinateurs elle était seulement de 8 bits, c'est-à-dire que pour envoyer un mot
(16 bits), il fallait procéder en deux étapes. Sur le 386, le bus de données est
de 32 bits, donc on peut envoyer un double-mot en une seule opération.
-
Déposez votre CV
-
lien de téléchargement direct
-
50 tirages offerts à l'inscription chez myPIX.com!
-
Dépot de CV gratuit sur Touslesemplois
-
Logiciel de référencement automatique
|