PROFDINFO.COM

Votre enseignant d'informatique en ligne

Organisation de la mémoire

Réponses aux questions et exercices

1- Pourquoi un système qui utilise de la mémoire virtuelle est-il plus lent qu'un système qui n'en utilise pas?

La mémoire virtuelle est un simple fichier sur un disque dur. Le disque dur est beaucoup plus lent que la mémoire vive, car il demande de faire tourner un disque et déplacer une tête de lecture, alors que la mémoire vive est un simple circuit intégré dans lequel passe des courants électriques.

2- Pourquoi utiliser la mémoire virtuelle si elle ralentit l'ordinateur?

Parce qu'elle permet d'étendre la mémoire vive si on n'en a plus. Si on n'utilisait pas la mémoire virtuelle, on ne pourrait plus démarrer d'autres applications lorsque la mémoire vive serait pleine. On fait un compromis entre rapidité et possibilité d'exécuter plus d'applications simultanément.

3- Donnez deux grandes différences entre les pages et les segments en mémoire.

Les pages sont de taille fixe, les segments de taille variable.

Les pages sont invisibles pour les programmes en mémoire qui ne voient qu'un grand espace contigu, mais les segments sont visibles et un programme peut choisir dans quel segment placer certaines données.

4- Pourquoi une erreur de page majeure n'est pas réellement une erreur en tant que telle?

Une erreur de page majeure survient lorsqu'un processus tente d'accéder à des informations d'une page qui n'est pas chargée en mémoire vive. C'est le signal que le système d'exploitation attend pour la charger, dans le cas où il a choisi de ne charger que le minimum d'abord, ou s'il a placé cette page dans la mémoire virtuelle. Ce n'est pas réellement une erreur car le système d'exploitation sait qu'elle va arriver et attend ce moment pour charger la page en mémoire vive.

5- Nommez trois situations qui peuvent mener à une erreur de segmentation.

Lorsqu'un processus tente d'accéder à un segment invalide, à un segment auquel il n'a pas accès ou d'une façon interdite (comme en écriture dans un segment où il a un accès en lecture seulement).

6- Quelles sont les trois opérations que l'ont peut faire sur une pile et en quoi consistent-elles?

Push: empiler quelque chose sur le dessus de la pile.

Pop: enlever la chose qui se trouve sur le dessus de la pile (pour en faire ce que l'on veut).

Peek: regarder la chose qui se trouve sur le dessus de la pile, mais en la laissant là.

7- Qu'empile-t-on sur la pile d'exécution?

Des contextes d'éxécutions, c'est à dire les paramètres et variables locales à une fonction, les données auxquelles la fonction aura accès.

8- Prenez l'exercice 4.6 de votre cours d'algorithmie. Dessinez le contenu de la pile d'exécution une fois que le main a appelé GererMenu et que GererMenu a appelé AfficherMenu. Imaginez les adresses des fonctions mais soyez cohérents!

On supposera que le main est empilé à l'adresse 0x1000, pour plus de simplicité. On sait que le main n'a pas reçu de paramètres (puisqu'il est appelé en tout premier), on n'empilera alors que ses variables locales (combien il en utilise dépendra de votre programme, qui pourra différer du mien).

Le main aura empilé les deux paramètres qu'il passe à GererMenu, BorneMin et BorneMax, puis son adresse de retour (0x1000). GererMenu empilera ses variables locales (encore une fois, les variables pourront être différentes d'une personne à l'autre).

Par-dessus tout ça, GererMenu empilera lui aussi les paramètres qu'il passe à AfficherMenu, toujours BorneMin et BorneMax. Il empile aussi son adresse de retour (qu'on trouvera en regardant combien d'octets on a empilés), puis AfficherMenu empile ses variables locales. C'est là qu'on s'arrête. Le pointeur d'exécution pointera vers le contexte de AfficherMenu.

On sait qu'un int prend 4 octets, donc on fera monter les adresses de 4 à chaque fois qu'on en empile un. Une adresse de retour n'est rien d'autre qu'un int également (qui contient le nombre correspondant à l'adresse).

Le résultat pourrait donc être:

9- Pourquoi est-ce que GererMenu ne peut pas accéder aux variables déclarées dans AfficherMenu?

Parce que lorsque GererMenu est en exécution, AfficherMenu n'est pas encore sur la pile (ou vient d'être enlevé). Les variables d'AfficherMenu ne sont accessibles qu'à AfficherMenu, pendant qu'il est sur le dessus de la pile, en train d'être exécuté.

10- Lorsque les mots du processeur avaient une taille de 16 bits, quel était la capacité maximale de la mémoire vive (RAM) qui était adressable (et donc utilisable)? Expliquez avec des calculs.

Avec un mot de 16 bits, on peut créer 216 adresses mémoires, soit 65 536. Chacune de ces adresses est attribuée à un octet en mémoire, donc on peut adresser une taille maximale de 65 536 octets. 65 536/1 024 = 64 Ko. Avec un processeur 16 bits, on peut adresser 64 Ko seulement!

11- Si l'intervalle de mémoire suivant contient les données suivantes:

 

0x00000B33341D-0x00000B333416 : 1900 DDA0 2113 4735

a) Quel caractère (char) se trouve à l'adresse 0x00000B333419? (nommez le caractère qui serait affiché à l'écran)

L'adresse 0x...19 contient 0x21 (puisque l'adresse 0x...16 est celle de l'octet 0x35 à droite, on remonte d'un octet vers la gauche pour chaque adresse).

0x21, selon la table ASCII, correspond au caractère "!". Attention, 0x21 est en hexadécimal et vaut 33!

b) À quelle adresse se trouve l'entier (int) 0x1900 DDA0?

L'adresse d'une variable est l'adresse de son octet au poids le plus faible. On cherche donc l'adresse de 0xA0, soit 0x00000B33341A.

c) Quel entier court non signé (unsigned short) se trouve à l'adresse 0x000000B33419? (donnez le nombre en système décimal et indiquez votre démarche)

L'adresse est celle de l'octet au poids le plus faible du short. Le short prend 2 octets, on parle donc du nombre 0xA021 (0x21 étant à l'adresse 0x...19, et on étend d'un octet vers la gauche). 0xA021, en binaire = 1010 0000 0010 0001, soit 1x32 768 + 1x8 192 + 1x32 + 1x1 = 40 993.

d) Quel entier (int) se trouve à l'adresse 0x00000B333416? (donnez le nombre en système décimal et indiquez votre démarche)

Encore une fois, l'adresse donnée correspond à l'octet le plus faible du int, qui compte 4 octets. Le int sera donc 0x2113 4735, soit 0010 0001 0001 0011 0100 0111 0011 0101. Le calcul est plus long avec un int, mais on additionne les puissances de deux: 1 + 4 + 16 + 32 + 256 + 512 + 1 024 + 16 384 + 65 536 + 131 072 + 1 048 576 +16 777 216 + 536 870 912 = 554 911 541. On peut aussi utiliser le convertisseur fourni dans les notes de cours pour arriver rapidement à la réponse, comme le calcul est plutôt ardu.

e) Quel flottant (float) se trouve à l'adresse 0x00000B333416? (donnez le nombre en système décimal et indiquez votre démarche)

Un float contient le même nombre d'octets qu'un int, donc le float situé à cette adresse sera la même donnée que le int du numéro précédent: 0x2113 4735. La différence est au niveau de l'interprétation. 0x2213 4735 = 0010 0001 0001 0011 0100 0111 0011 0101.

Interprété comme un float, ça signifie que le bit de gauche (bit de signe) est à 0: notre float est positif.

Les huit bits qui suivent sont l'exposant: 0100 0010, soit 64 + 2 = 66 - 127 = -61. Notre float sera un très petit nombre, plus petit que 1, donc zéro virgule quelque chose de petit.

Les 23 bits qui restent sont la mantisse. Si on écrit 1,mantisse x 2exp, on obtient: 1,0010 0110 1000 1110 0110 101 x 2-61.

Il faut donc déplacer la virgule de 61 positions vers la gauche! On obtient alors 0,0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 1001 0011 0100 0111 0011 0101! Un bien petit nombre, en effet!

La partie entière est 0. La partie décimale est une addition de minuscules fractions: 2-61 + 2-64 + 2-67 + 2-68 + 2-70 + 2-74 + 2-75 + 2-76 + 2-80 + 2-81 + 2-83 + 2-85! On peut additionner tout ça, mais dans un cas de ce genre, le convertisseur fourni dans les notes de cours nous sera fort pratique pour découvrir que le nombre est environ 1.99599 x 10-18.