I. DEFINITION DE DONNEES ET ADRESSAGE
1. Les définitions de données
Les mots “db” (« define byte »),
“dw” (« define word »), ”dd”
(« define double word ») permettent de
déclarer et d’initialiser une variable. Il faut bien
comprendre que leur seule action est d’écrire les
données dans l’exécutable à l’endroit
même où elle se trouvent dans le code source.
Pour accéder à ces données (appelées
« variables »),
il suffit de connaître leur adresse. Pour cela, on peut les faire précéder
d’un label de données.
Exemple :
TOTO dw 1982
Dans la ligne précédente, TOTO représente l’adresse
du nombre 1982 qui est défini juste après. Comme ce
nombre est codé sur deux octets (word = 16 bits), c’est
le premier octet qui est adressé par TOTO.
Le compilateur se contentera d’écrire le nombre 1982 à
l’endroit où se trouve la déclaration.
Remarque :
en C, on écrirait ceci :
int TOTO = 1982;
En BASIC ou en PASCAL, cette définition n’a pas
d’équivalent, puisque les variables ne peuvent être
initialisées lors de leur déclaration. Il est donc
obligatoire d’ajouter une ligne de code pour le faire.
Dans la partie précédente, nous avons eu à définir
le message qui serait affiché à l’écran.
Voici la ligne que nous avons écrite :
message db “Bonjour, monde !”, ‘$’
Lorsqu’il rencontre une chaîne de caractères, le compilateur écrit
les codes ASCII de tous les
caractères, les uns à la suite des autres.
Voici une autre manière d’écrire cette définition
de données. Le résultat (i.e. le programme compilé)
est EXACTEMENT LE MÊME :
message db 42h, 111, ‘nj’
db ‘our, mo’
db ‘nde !$’
Pour définir plusieurs fois à la suite les mêmes
données, on utilise “DUP” (« duplicate »)
de la manière suivante :
TOTO db 100 dup(“TOTO EST BEAU”)
Cela revient à écrire :
TOTO db “TOTO EST BEAU”
TOTO db “TOTO EST BEAU”
TOTO db “TOTO EST BEAU”
;… etc (100 fois) …
Il est fréquent que de nombreuses données n’aient
pas besoin d’être initialisées à une valeur
précise. Dans ce cas, on les regroupe à la fin du
programme et on les remplace par le caractère ‘?’.
Les adresses des labels seront calculées de la même
façon mais aucune données ne sera écrite dans le
fichier (et a fortiori dans la RAM). On dit que l’on met ses
variables sur le « tas »
(« heap »
en anglais). La seule différence avec une définition
classique est qu’au début de l’exécution,
nos variables n’auront pas de valeur définie. Leurs
valeurs seront « aléatoires » en ce sens
qu’on ne peut les connaître au moment de la compilation.
Exemple :
Remarque :
Si elles ne sont pas regroupées en fin de programme, le
compilateur sera obligé d'écrire les données
dans le fichier afin de ne pas fausser les adresses des variables (ou
du code) qui suivent. Il remplira alors les points d’interrogation
avec des zéros.
Pour indiquer qu’un chiffre est noté en base hexadécimale,
on lui ajoute la lettre ‘h’. La lettre ‘b’
signifie que le chiffre est codé en binaire, la lettre 'o' en
octal et la lettre ‘d’ en base décimale (base par
défaut).
2. L’adressage
a) l’adressage immédiat
On appelle « adressage immédiat »
l’adressage qui ne fait intervenir que des constantes.
Considérons cette partie de programme qui stocke le nombre 125h dans une variable
appelée TOTO, lui ajoute 15 puis charge le résultat
dans AX.
La ligne
mov word ptr ds:[TOTO], 125h
charge le nombre 125h dans le mot de la RAM adressé par DS et
l’offset de “TOTO”. La ligne suivante ajoute 15 au
contenu de ce mot.
L’expression “word ptr” devant l’adresse, obligatoire ici,
indique la taille de la variable dans laquelle doit être stocké
le nombre 125h.
Si on avait mis “dword ptr”, ce nombre aurait été
codé sur 32 bits (00000125h) au lieu de 16 bits (0125h) :
on aurait donc écrasé les deux octets qui suivent la
variable. Si on avait mis “byte ptr”, la compilation
aurait été impossible car un octet ne peut contenir un
nombre supérieur à FFh.
Le compilateur n’a en effet aucun moyen
de connaître cette taille. La variable “TOTO” n’a
pas de taille (malgré le mot “dw”) : ce n’est
en fait qu’un pointeur vers le premier octet du word
qu’elle représente.
En revanche, la troisième instruction ne fait pas apparaître
l’expression “word ptr”. Cette fois-ci elle est
facultative du fait que la destination (AX = 16 bits) impose la
taille.
On peut évidemment remplacer “TOTO” par une
constante numérique :
mov word ptr ds:[004Ch], 125h
Le mot 125h sera alors écrit à l’adresse DS:4C.
Une question se pose à présent : que se passe-t-il
si le programmeur n’écrit pas le registre de segment
dans l’adresse ?
C’est là qu’intervient la directive “assume”. Le
compilateur va devoir trouver lui-même quel registre
l’utilisateur a voulu sous-entendre.
Si on a utilisé un label, alors le segment sera celui dans lequel
est déclaré le label. Mais le compilateur veut un
REGISTRE de segment. Il va donc prendre celui qui est censé
pointer vers le bon segment et pour le savoir, il examine la
directive assume.
Voilà pourquoi cette dernière peut nous épargner d’écrire
pour chaque variable l’expression “ds:”.
Comprenez bien que cette directive ne sert à rien d’autre qu’à
cela et qu’en aucune façon elle ne force les registres de
segment à prendre quelque valeur que ce soit.
b) l’adressage indexé et/ou basé
Comme nous l’avons déjà expliqué, il est
possible d’utiliser des registres de base
ou d’index pour
adresser un octet.
On appelle « base » les registres BX et BP
et « index » les registres SI et DI. La
différence est que la base est censée être fixe
tandis que l’index varie automatiquement lorsqu’on
utilise certaines opérations, telles que MOVSB.
Remarque :
BX, BP, DI et SI peuvent tous être utilisés comme des
registres généraux.
Voici les adressages possibles:
Exemples :
MOV AH, byte ptr [TOTO]
MOV BX, word ptr ds:[1045h]
MOV ES:[10 + TOTO x 2], BL
Exemple :
MOV dword ptr ds:[BP], 15
Exemple :
MOV dword ptr es:[DI], 142
Exemples :
MOV byte ptr ds:[BP + 1], 12
MOV ds:[BX + (TOTO – BOBO)/10], AX
Exemples :
MOV CX, [TOTO + DI]
MOV AL, ds:[1 + SI]
Exemple :
MOV ds:[BP + SI], AH
Exemple :
MOV AX, word ptr [TOTO + BX + DI + 1]
Remarque :
si la constante n’est pas un label, il est parfois impératif
de spécifier le registre de segment ! Tout dépend
du contexte…
Sommaire
Suite
|