Copy Link
Add to Bookmark
Report

Tutorial Assembleur - Chapitre 06

eZine's profile picture
Published in 
Tutorial Assembleur
 · 11 Oct 2020

  

TUTORIAL ASSEMBLEUR - chapitre 6
--------------------------------

La mémoire
----------

La mémoire et ses instructions
------------------------------

J'ai déjà écrit une introduction sur la mémoire de l'ordinateur dans la leçon 1, mais nous
allons aborder sa mise en place et voir d'une façon plus précise, la manière de l'utiliser.
Attention : nous travaillons pour l'instant en mode réel, le code protegé demande du code
différent.

Il existe pour cela plusieurs instructions. Nous avons vu que "MOV SI, offset MESSAGE" plaçait
dans SI, la valeur de l'offset de MESSAGE. Pour une donnée dans un autre segment, il faut
aussi utiliser le "MOV AX,seg MESSAGE" et ensuite "MOV DS,AX". En effet, les registres ES, DS,
FS et GS n'acceptent pas de valeur numérique directe mais seulement des registres.

Il existe une autre instruction, LEA, qui permet de placer l'offset dans un registre mais
en plus court. Par exemple "LEA SI,MESSAGE" placera dans SI, l'offset de Message.
Privilégiez l'emploi de LEA plutôt que du MOV. Cela rend le code plus clair et plus compact.

Pour pouvoir déplacer des blocs entiers de mémoire, nous n'allons pas lire chaque octet et
le placer dans l'autre bloc mais nous employerons les instructions :

MOVSB
MOVSW
MOVSD

La première pour déplacer une (B)ytes, la deuxième un (W)ord et la dernière pour déplacer
un (D)words qui font 32 bits.
Ces instructions demandent que la source (DS:SI) et l'arrivée (ES:DI) soient configurées.
Il ne faut pas diriger les données vers n'importe quel emplacement de la mémoire.
Vous planteriez à coup sur le programme. Nous verrons plus loin, comment allouer des blocs
de mémoire.

Par exemple dans DS:SI, nous pouvons avoir les données d'une image et dans ES:DI, l'adresse
de la mémoire video (A000h:0000). Si nous voulons copier 10000 bytes, nous employerons
directement le MOVSD (si nous travaillons avec un 386 ou plus) ou avec MOVSW.
Pour plusieurs MOVSx, il est inutile de faire une boucle. L'instruction REP est là pour cela.
Il faut utiliser conjointement avec REP, le registre CX qui contient le nombre
d'itérations (le nombre de fois que l'on répete le MOVSx).

Pour les 10000 bytes, nous avons :

MOV CX,10000
REP MOVSB

Si nous utilisons les Words (plus rapide), c'est :

MOV CX,5000 (un word=2 bytes)
REP MOVSW

Finalement, avec le 32 bits, c'est :

MOV ECX,2500 (un dword=2 words=4 bytes) - utilisation d'un registre étendu
REP MOVSD

A chaque MOVSx, DI augmente de 1,2 ou 4 bytes.


Maintenant, si nous voulons garder des données ou les placer dans un emplacement de la mémoire ?
Nous utiliserons les instructions :

STOSB
STOSW
STOSD

Comme pour les MOVSx, cette instruction stocke un byte, un word et un dword.
A la différence des déplacements, les STOSx utilisent AL, AX (EAX 32bits) comme valeur à
stocker. La valeur de AL,AX,EAX sera stockée dans ES:DI. A chaque STOSx, DI est
augmenté de 1,2 ou 4 bytes. Ces instructions sont utiles pour effacer l'écran par exemple
ou remplir un bloc mémoire avec la même valeur.

MOV CX,1000
MOV AX,0
REP STOSB

Dans cette exemple, CX équivaut à 1000, pour 1000 répétitions. Ensuite, le MOV AX,0 qui est
la valeur qui sera placée dans le bloc mémoire. Pour finir, le REP STOSB qui dit que nous
plaçons 10000 bytes de valeur 0 à l'emplacement de ES:DI. En fait, ici nous placons
AL, on ne tient pas compte de AH dans un STOSB.

Pour réserver de la mémoire, il faut employer les interruptions, ici nous restons
dans la mémoire conventionnelle, c'est à dire que l'on ne dépasse pas les 640ko attribués
par le DOS. Si l'on veut plus de mémoire, il faut utiliser les modes dits protégés ou
flat. La programmation de ces modes est différentes et il faut avoir quelques notions sur le DOS
et la gestion de la mémoire. Si vous voulez dès maintenant en savoir plus, lisez des
documentations comme celles d'Intel.

Pour la mémoire conventionnelle, on doit d'abord libérer l'emplacement occupé par notre
programme :

MOV BX,taille ; la taille=(taille du prog en octet / 16)+1
MOV AH,04ah
INT 21h

Ici, taille=4096 correspond 64ko. Ajustez donc la taille en fonction de votre programme.
J'ai ajouté 1 à la taille pour éviter des erreurs (normalement pas nécessaire, on ne
sait jamais ;).

Ensuite, il faut réserver le bloc de mémoire:

MOV AH,48h
MOV BX,mem_voulue ; (mem_voulue=memoire_desiree/16)+1))
INT 21h
JC NOT_ENOUGH_MEM

La mémoire voulue se calcule comme pour la libération de la mémoire. Le JC NOT_ENOUGH_MEMORY
est utile pour détecter les erreurs. Si la mémoire n'est pas disponible, votre programme
ira au label NOT_.... et fera ce que vous voulez pour indiquer l'erreur
(affichage d'un texte, retour au DOS). IMPORTANT, il faut conserver la valeur de
AX après avoir exécuté le INT 21h. AX contient le segment du bloc alloué et il
faut garder cette valeur pour pouvoir la réutiliser lors du désallouage.

Finalement, il faut désallouer les blocs de mémoire APRES les avoir utilisé (sinon quel intérêt ?).

MOV BX,4096 ; (taille du bloc)
MOV AX,segment_bloc ; (le segment du bloc, nous l'avons précieusement gardé)
MOV ES,AX
MOV AH,49h
INT 21h

Le fait de ne pas désallouer de la mémoire va vous en enlever pour des programmes qui
seraient exécutés par la suite.

### Chapitre 6 - dake / c a l o d o x ###
### http://www.space.ch/scene/calodox ###

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT