Dans le mode protégé, chaque processus possède son propre espace d'adresses virtuelles. Cela signifie que toute adresse manipulée par le processus n'a de sens que pour lui et lui seul. Une adresse 0x12345678 d'un processus peut désigner une structure quelconque, tandis que la même adresse 0x12345678 dans un autre processus peut désigner tout autre chose, ou bien être invalide.
[haut de page]La plupart des programmes a souvent besoin d'accéder aux mêmes données partagées (par exemple, les DLLs). Dupliquer chaque DLL dans l'espace virtuel de chaque processus serait un gâchis. De même, lorsque plusieurs instances d'un même programme sont lancées, il est inutile de charger plusieurs fois le même code.
Le mapping consiste à associer une plage d'adresses dans l'espace d'adresses du processus à des pages mémoire de Windows. Ces pages peuvent se trouver soit en mémoire physique, soit dans le fichier d'échange.
Dans la figure ci-dessus, les processus 1 et 2 sont deux instances d'un même programme. Ce programme est composé d'une page de code et de deux pages de données. Chaque processus partage la même page de code en lecture seule (pas forcément à la même adresse virtuelle).
Les deux pages de données sont accessibles en lecture / écriture. Tant que les processus ne modifient pas les données, ils partagent les mêmes pages. Lorsqu'un processus modifie les données, il obtient une copie exclusive de la page.
[haut de page]Lorsque des exécutables sont lancés, on peut normalement penser que ces fichiers sont entièrement copiés en RAM, puis exécutés. Si jamais la RAM vient à manquer, ils sont sauvés dans le fichier de swap. Ce n'est absolument pas ce qui se passe : si Windows devait recopier en mémoire chaque programme lancé, cela ralentirait considérablement le temps de chargement.
Windows réserve une plage d'adresses virtuelles qu'il associe avec le fichier de l'exécutable, comme si celui-ci faisait partie de la swap : cette opération s'appelle le mapping du fichier. Ainsi, seules les pages nécessaires sont chargées en mémoire vive.
Si les sections en lecture seule (code, données constantes) ou des sections en lecture / écriture qui n'ont pas été modifiées ne sont pas présente en RAM, elles seront rechargées directement depuis le fichier exécutable. Seules les sections en lecture / écriture et modifiées sont sauvegardées dans la swap.
La technique de Windows pour charger des programmes peut être utilisée pour n'importe quel fichier. Lorsqu'un programme utilisateur mappe un fichier en mémoire, le contenu du fichier est rendu accessible au programme, et peut être manipulé comme n'importe quelle autre zone mémoire.
[haut de page]Les processus manipulent des pointeurs 32 bits. Ces pointeurs peuvent donc prendre n'importe quelle valeur comprise entre 0x00000000 et 0xFFFFFFFF, soit 4'294'967'295 valeurs différentes possibles. Sur ces valeurs, un processus peut manipuler, pour son usage personnel, environ 2 Go (soit 50%). Voici comment est partitionné l'espace virtuel de chaque processus.
Partition | Windows 98 | Windows 2000/XP | Rôle |
---|---|---|---|
NULL-pointeur assignment | 0x00000000 0x00000FFF |
0x00000000 0x0000FFFF |
Zone toujours interdite d'accès pour capturer les erreurs liées aux pointeurs NULL. |
Dos compatibility | 0x00001000 0x003FFFFF |
Cette zone de 4 Mo existe pour maintenir la compatibilité avec les applications Dos et Windows 16 bits. | |
User-mode | 0x00400000 0x7FFFFFFF |
0x00010000 0x7FFEFFFF |
Espace mémoire utilisable par un processus. Avant de pouvoir lire ou écrire dans cette zone, le processus doit faire une demande d'allocation mémoire |
Off-Limit | 0x7FFF0000 0x7FFFFFFF |
Protéger d'éventuels overflows la zone système en créant délibérément une frontière-tampon de 64 Ko interdite d'accès. | |
Shared Memory-Mapped File | 0x80000000 0xBFFFFFFF |
Zone de chargement des données partagées entre tous les processus (Kernel32.dll, User32.dll, ...) et des fichiers mappés. | |
Kernel-Mode | 0xC0000000 0xFFFFFFFF |
0x80000000 0xFFFFFFFF |
Zone où réside le code du système d'exploitation. |
En théorie, un processus ne PEUT pas accéder à l'espace mémoire d'un autre processus. Puisque chaque valeur que peut prendre un pointeur fait référence à l'espace virtuel du processus, il n'est pas possible d'obtenir un pointeur vers l'espace mémoire d'un autre processus.
Dans la pratique, certains programmes ont besoin d'accéder à la mémoire virtuelle d'autres applications (par exemple, les débogueurs... ou les virus ;-). Microsoft fournit plusieurs fonctions qui permettent de manipuler la mémoire des processus. Celles-ci sont détaillés dans la section suivante "APIs".
[haut de page]Voici les fonctions les plus intéressantes à connaître concernant la manipulation de la mémoire sous Windows. Les autres peuvent facilement être retrouvées dans le chapitre "Memory Management" de la MSDN.
Crée un file mapping object pour un fichier donné. Cet objet peut être ouvert par d'autres applications avec OpenFileMappingObject.
Mappe la totalité ou une partie d'un fichier dans l'espace d'adresses virtuelles du processus courant. Un file mapping object doit avoir été créé avec CreateFileMapping.
Réserve ou alloue une partition dans l'espace d'adresses virtuelles d'un processus. Cette fonction convient beaucoup aux allocations importantes de mémoire ( > 64 Ko ). Pour les "petites" allocations, il est préférable d'utiliser les fonctions de tas (HeapAlloc et malloc). Pour libérer la mémoire allouée avec VirtualAlloc, il convient d'utiliser VirtualFree.
Etant donné un pointeur de valeur quelconque, renvoie l'état, la taille, la position, les protections de la partition de mémoire à laquelle il appartient. Les différents états sont : non alloué, non alloué mais réservé, alloué.
Avec NULL passé en paramètre, le handle renvoyé est l'adresse de chargement du fichier exécutable. Cette zone est accessible en lecture, vous pourrez y lire l'en-tête EXE du fichier.
Teste si le processus a droit de lecture / d'écriture sur la zone mémoire pointée. Le pointeur passé en paramètre peut avoir n'importe quelle valeur.
Copie une zone mémoire vers une autre.
Renvoie l'état, la taille, la position, les protections d'une partition de mémoire de n'importe quel processus.
Crée un thread dans l'espace virtuel d'un autre processus. Le code du thread doit exister dans l'espace virtuel du processus.
Permet de lire et d'écrire dans la mémoire de n'importe quel processus.
Si vous avez apprécié (ou détesté) cet article ou ce site, vous avez la possibilité de donner une note d'évaluation et indiquer les points forts, les points faibles de ce site. Ce service est offert par l'institut de statistiques Weborama.
Eric Minso - novembre 2003 - La Caverne Informatique - http://cavinfo.fr.st/