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

La mmoire
----------

La mmoire et ses instructions
------------------------------

J'ai dj crit une introduction sur la mmoire de l'ordinateur dans la leon 1, mais nous 
allons aborder sa mise en place et voir d'une faon plus prcise, la manire de l'utiliser.
Attention : nous travaillons pour l'instant en mode rel, le code proteg demande du code
diffrent.

Il existe pour cela plusieurs instructions. Nous avons vu que "MOV SI, offset MESSAGE" plaait 
dans SI, la valeur de l'offset de MESSAGE. Pour une donne 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 numrique 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. 
Privilgiez l'emploi de LEA plutt que du MOV. Cela rend le code plus clair et plus compact.

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

MOVSB
MOVSW
MOVSD 

La premire pour dplacer une (B)ytes, la deuxime un (W)ord et la dernire pour dplacer 
un (D)words qui font 32 bits. 
Ces instructions demandent que la source (DS:SI) et l'arrive (ES:DI) soient configures. 
Il ne faut pas diriger les donnes vers n'importe quel emplacement de la mmoire. 
Vous planteriez  coup sur le programme. Nous verrons plus loin, comment allouer des blocs
de mmoire.

Par exemple dans DS:SI, nous pouvons avoir les donnes d'une image et dans ES:DI, l'adresse 
de la mmoire 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'itrations (le nombre de fois que l'on rpete 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 donnes ou les placer dans un emplacement de la mmoire ?
Nous utiliserons les instructions : 

STOSB
STOSW
STOSD

Comme pour les MOVSx, cette instruction stocke un byte, un word et un dword. 
A la diffrence des dplacements, les STOSx utilisent AL, AX (EAX 32bits) comme valeur  
stocker. La valeur de AL,AX,EAX sera stocke 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 mmoire avec la mme valeur.

MOV CX,1000
MOV AX,0
REP STOSB

Dans cette exemple, CX quivaut  1000, pour 1000 rptitions. Ensuite, le MOV AX,0 qui est 
la valeur qui sera place dans le bloc mmoire. Pour finir, le REP STOSB qui dit que nous 
plaons 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 rserver de la mmoire, il faut employer les interruptions, ici nous restons 
dans la mmoire conventionnelle, c'est  dire que l'on ne dpasse pas les 640ko attribus 
par le DOS. Si l'on veut plus de mmoire, il faut utiliser les modes dits protgs ou
flat. La programmation de ces modes est diffrentes et il faut avoir quelques notions sur le DOS 
et la gestion de la mmoire. Si vous voulez ds maintenant en savoir plus, lisez des 
documentations comme celles d'Intel.

Pour la mmoire conventionnelle, on doit d'abord librer 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 ncessaire, on ne 
sait jamais ;).

Ensuite, il faut rserver le bloc de mmoire:

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

La mmoire voulue se calcule comme pour la libration de la mmoire. Le JC NOT_ENOUGH_MEMORY 
est utile pour dtecter les erreurs. Si la mmoire 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 aprs avoir excut le INT 21h. AX contient le segment du bloc allou et il 
faut garder cette valeur pour pouvoir la rutiliser lors du dsallouage.

Finalement, il faut dsallouer les blocs de mmoire APRES les avoir utilis (sinon quel intrt ?).

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

Le fait de ne pas dsallouer de la mmoire va vous en enlever pour des programmes qui
seraient excuts par la suite.

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