|
Comprendre l'assembleur |
Un ordinateur est une machine qui traite les informations d’une façon automatique, ces informations peuvent être de différents type (image, son, nombre…), donc ce qu’il faut savoir c’est qu’une information se présente dans l’ordinateur comme une suite ordonnée de 0 et 1.
Mais comment un ordinateur
traite un programme ? Vous avez déjà écrit un programme dans un langage binaire,
je pense que ça sera impossible vous n’aurez devant vous que des ligne de 0 et
1 ! Donc on a chercher a trouver une codification plus facile a manier, alors
surgit l’hexadécimal plus facile que le binaire, mais pose un autres problème,
les codes écris en hexadécimal reste aussi très difficile a déchiffrer,
exemple : l’addition est représenter en hexadécimal par C6, je ne pense pas que
vous l’avez devinez
mais si je vous dit ADD, la je vois que tout le monde la vite compris ADD c’est
l’abréviation de addition elle est plus facile à retenir. Vous venez de
connaître le langage assembleur, c’est un ensemble de code ou abréviation
(facile a retenir) du genre ADD, MOV, XOR… qui n’est rien d’autre que la
"surcouche" du langage machine donc c’est le langage de bas niveau c’est lui qui
est le plus proche de la machine : quand vous écrivait un programme en langage
assembleur il est traduit directement en langage machine. Mais si vous écrivait
un programme avec un langage évolué (Delphi, Visual Basic, Fortran, Langage C,
Visual C++ et pleins d’autres) l’ordinateur ne peut pas le comprendre donc il
doit être traduit en langage machine grâce a un compilateur ou interpréteur,
mais ce-ci n’est pas l’objectif de ce cours.
Pour information
l’hexadécimal est un système de numérotation ou les nombres sont représentés à
l’aide de 16 chiffres, pour cela on prend les chiffres arabes (0 1 2 3 4 5 6 7 8
9) et les six premiers caractères alphabétique (A B C D E F). Vous me direz
pourquoi prendre des caractères alphabétiques ? La réponse est simple il y a pas
d’autres chiffres que 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 dix en total, on a pas
inventer d’autres
donc
on les prends de l’alphabet elle doit aussi servir non ? On obtient ça à la
fin :
| Décimal | Binaire | Hexadécimal |
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 2 | 0010 | 2 |
| 3 | 0011 | 3 |
| 4 | 0100 | 4 |
| 5 | 0101 | 5 |
| 6 | 0110 | 6 |
| 7 | 0111 | 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 |
NOTE :
si je vous donne un nombre, par exemple 354, pouvez vous savoir si c’est un
nombre décimal ou hexadécimal ?! Bien sur que non
donc
pour enlever ce conflit on met après le nombre le caractère h pour
l’hexadécimal et un d pour dire que c’est du décimal. Donc ça nous
donne : 354h le petit h (ou d) ne fait pas partie du nombre 354 (il ne faut pas
le noter, c’est qu’un signe pour dire que c’est de l’hexadécimal).
Les instructions Assembleur :
Vous avez maintenant une idée
sur ce qu’est l’assembleur, mais avant d’aborder les instructions assembleur il
faut savoir ce qu’est un bit, octet, registre…
Un bit peut être décrit comme
étant la plus petite unité de la mémoire, et un octet est constitué de 8 bits,
[1 Ko (kilo octets) = 210 octets = 1024 octets].
Ce que vous devez encore savoir c’est qu’un registre est un espace mémoire ou on peut stocker des valeurs, donc ces emplacements ou se trouvent les octets sont des adresses mémoires, segment & offset : imaginez un tableau, par quoi est-il constituer ? des lignes et des colonnes, donc un espace mémoire c’est comme une cellule dans un tableau, si on veut donner une adresse pour cette cellule, elle doit être constituer de deux adresses celle de la colonne et l’autre de la ligne, dans notre cas l’adresse de la colonne (partie haute) c’est le segment et l’adresse de la ligne c’est l’offset, en général ça s’écrit comme ça : segment:[offset] mais pas obligatoirement. Il existe plusieurs type de registres et avec chacun un but bien précis (ça dépend)
Sur ce cours je ne vous donne pas toutes les instructions mais l’essentiel à connaître:
L’instruction MOV :
Cette instruction copie une source a une destination, elle s’écrit sous cette forme MOV [destination],[source] je donne un exemple : mov eax,00000001 donc cette ligne permet de mettre dans le registre eax la valeur 1

*
eax
est un registre 32 bits
* al
registre de 8 bits (niveau bas du registre eax)
Revenons a notre exemple mov eax,01 il sera représenter comme suit : eax=00000001 retenez bien que c’est q’un simple exemple et que eax peut avoir d’autres valeurs.
L’instruction CALL :
Cette instruction appelle une
procédure (sous routine) : une routine de génération du code d’enregistrement
par exemple, le CALL peut aussi appeler une boite de dialogue (nag) si vous ne
savez pas ce qu’est un nag alors passez voir la rubrique Protection sur le site,
il y a une liste des protections software (standards).
Un CALL s’écrit toujours de
cette façon : call [adresse] sachez bien qu’un call est suivi
d’une adresse du genre CALL 004465B8.
(pas toujours)
A la fin de la procédure que
le CALL appel il y a toujours un RET. Qui revient a la ligne
juste après le call, nous verrons tout ça sur les prochains cours, il faut juste
bien suivre.
L’instruction PUSH & POP :
L’instruction PUSH permet de mettre une valeur dans la pile, PUSH [valeur]
& POP permet de prendre une
valeur depuis la pile et de la mettre dans un registre, POP [registre]

* esp est un registre pointeur 32 bits
L’instruction CMP :
Cette instruction permet de
comparer entre deux variables CMP [variable],[variable]
Donc pour comparer eax et ebx
cette instruction soustrait eax à edx (eax-ebx), à noter qu’aucune variable
n’est modifié mais seulement un indicateur dit FLAG.
Exemple : CMP EAX,EBX
JNE 00406543
La 1ère ligne compare eax et
ebx (eax-ebx) si eax-ebx=0 cela voudra dire que l’indicateur de l’instruction
JNE sera mis à zéro (jne = saut si pas égal à 0) devinez la suite ;-)
Cette
instruction est toujours suivit d’un saut conditionnel.
* flag c’est un indicateur que des instructions utilises (tel que les sauts conditionnels) afin de vérifié le résultat d’une opération, donc une instruction dépend de la valeur trouvé dans un indicateur.
L’instruction J[?] Les sauts conditionnels :
Il y a beaucoup de sauts conditionnels leurs travail c’est de sauter a une adresse précise, je prend comme exemple JE saute si égal, donc si la condition est vrais le saut s’effectue à la partie souhaiter du programme, donc ce qu’i faut comprendre c’est qu’un saut (conditionnel) ne peut s’effectué sauf si la valeur que contient l’indicateur est vérifié. L’instruction CMP que nous avons vue précédemment compare entre deux valeurs mais elle ne modifie aucune (des valeurs) ce qu’elle modifie c’est l’indicateur, et cette valeur qu’il contiendra, influencera directement sur le saut ! Comme l’explique le tableau suivant :
|
Instructions Assembleur |
Code Hexadécimal |
Description |
Indicateurs |
| JNE | 75 ou 0F85 | Saute si pas égal (non égalité) | ZF=0 |
| JE | 74 ou 0F84 | Saute si égal (égalité) | ZF=1 |
| JA | 0F87 | Saute si au dessus (supérieur) | CF=0 et ZF=0 |
| JNA | 0F86 | Saute si ce n’est pas au dessus (non supérieur) | CF=1 ou ZF=1 |
| JL | 0F8C | Saute si c’est inférieur | SF!=OF |
| JLE | 0F8D | Saute si c'est inférieur ou égal | ZF=1 ou SF!=OF |
| JB | 0F82 | Saute si en dessous (inférieur) | CF=1 |
| JNB | 0F83 | Saute si pas en dessous (non inférieur) | CF=0 |
| JG | 0F8F | Saute si plus grand | ZF=0 et SF=OF |
| JNG | 0F8E | Saute si pas plus grand | ZF=1 ou SF!=OF |
Exemple :
JE 00402A3F (saute si égal, à l’adresse 00402A3F)
Il y a
encore d’autres mais c’est suffisant, une autre chose le
JLE JGE JG JL sont
utilisé très souvent pour la limitation du temps dans les logiciels
![]()
*
ZF [Zero
Flag ] si le résultat est nul cet indicateur sera mis à 1
*
CF
[Carry Flag] est le bit de retenue.
* SF
[Signe Flag] dans le cas d’un
résultat signé il est mis
à 1
*
OF [Overflow
] Flag utilisé dans le cas d’un dépassement
l’instruction XOR : [90h]
C’est le ou exclusif dans le principe est simple:
0 xor 0
donne 0
0 xor 1
donne 1
1 xor 0
donne 1
1 xor 1
donne 0
Ce qui
veut dire que xor modifie le bit d’une variable tel que le registre eax voila un
exemple :
xor eax,
eax cette instruction permet de forcer eax à 0.
L’instruction JMP : [EBh]
Ici
c’est le contraire d’un saut conditionnel abordé en haut, car c’est un saut
inconditionnel. Qu’est ce qu’il fait ? il saute tout simplement mais pas
n’importe ou puisqu’il est toujours suivi de l’adresse vers laquelle il doit
sauter
exemple :
JMP 0040564B
L’instruction NOP : [90h]
Comme son nom indique (no operation) elle ne fait rien, ouais rien, mais quel intérêt ? Vous verrez par la suite dans les prochains cours son utilité (indispensable).
|
Cours précédant : |
Cours suivant : |