Tout d’abord, cela n’a vraiment rien à voir avec la RAM. Nous parlons ici d' espace d'adressage - même si vous ne disposez que de 16 Mo de mémoire, vous disposez toujours de 32 bits d'espace d'adressage sur un processeur 32 bits.
Cela répond déjà à votre première question. En fait, au moment de sa conception, les PC du monde réel n’avaient nulle part près des 4 Go de mémoire; ils étaient plus dans la gamme de 1-16 Mio de mémoire. L'espace d'adressage était, à toutes fins pratiques, gratuit.
Maintenant, pourquoi 0xFFFFFFF0 exactement? Le processeur ne sait pas quelle quantité de BIOS il y a. Certains BIOS peuvent ne prendre que quelques kilo-octets, alors que d'autres peuvent occuper tout un mégaoctet de mémoire - et je n'entre même pas dans les différentes mémoires RAM optionnelles. Le processeur doit être câblé à une adresse quelconque pour commencer - il n'y a pas de configuration pour configurer le processeur. Mais il ne s'agit que d'un mappage de l'espace d'adressage - l'adresse est mappée directement dans la puce ROM du BIOS (oui, cela signifie que vous n'avez pas accès à la totalité des 4 Go de RAM à ce stade si vous en avez beaucoup - mais cela n’a rien de spécial, de nombreux périphériques ont besoin de leur propre plage d’adresses). Sur un processeur 32 bits, cette adresse vous donne 16 octets complets pour effectuer l’initialisation très basique - ce qui suffit pour configurer vos segments et, si nécessaire, le mode adresse (rappelez-vous,véritable démarrage "procédure". À ce stade, vous n’utilisez pas du tout de RAM, c’est juste une ROM mappée. En fait, la RAM n’est même pas prête à être utilisée à ce stade - c’est l’une des tâches du POST du BIOS! Vous vous demandez peut-être comment un mode réel de 16 bits peut accéder à l'adresse 0xFFFFFFF0? Bien sûr, il y a des segments, vous avez donc un espace d'adressage de 20 bits, mais cela ne suffit toujours pas. Eh bien, il y a une astuce: les 12 bits de poids fort de l'adresse sont définis jusqu'à ce que vous exécutiez votre premier saut en longueur, ce qui vous donne accès à l'espace d'adressage en hauteur (tout en refusant l'accès à une valeur inférieure à 0xFFF00000 - jusqu'à ce que vous exécutiez un saut en longueur) .
Tous ces éléments sont essentiellement masqués par les programmeurs (sans parler des utilisateurs) sur les systèmes d'exploitation modernes. Vous n’avez généralement accès à aucun niveau aussi bas - certaines choses sont déjà irrécupérables (vous ne pouvez pas changer de mode de processeur à tout moment), d’autres sont gérées exclusivement par le noyau du système d’exploitation.
Une vue plus agréable provient donc du codage old-school sous MS DOS. Un autre exemple typique de mémoire de périphérique mappée directement sur un espace d'adressage est l'accès direct à la mémoire vidéo. Par exemple, si vous voulez écrire rapidement du texte sur l’affichage, vous écrivez directement dans adresse B800:0000
(plus décalage - en mode texte 80x25, cela signifie que (y * 80 + x) * 2
si ma mémoire est fidèle - deux octets par caractère, ligne par ligne). Si vous vouliez dessiner pixel par pixel, vous utilisiez un mode graphique et l’adresse de départ de A000:0000
(typiquement, 320x200 à 8 bits par pixel). Faire quelque chose de très performant signifiait généralement plonger dans les manuels des appareils pour savoir comment y accéder directement.
Cela survit à ce jour - c'est juste caché. Sous Windows, vous pouvez voir les adresses de mémoire mappées aux périphériques dans le Gestionnaire de périphériques. Ouvrez simplement les propriétés de votre carte réseau, allez à l'onglet Ressources. Tous les éléments de la plage de mémoire sont des mappages de la mémoire du périphérique vers votre espace d'adressage principal. Et sur 32 bits, vous verrez que la plupart de ces périphériques sont mappés au-dessus de la marque 2 GiB (plus tard 3 GiB) - encore une fois, pour réduire les conflits avec la mémoire utilisable par l'utilisateur, bien que cela ne soit pas vraiment un problème avec la mémoire virtuelle ( les applications ne s'approchent pas de l' espace d'adressage matériel réel - elles ont leur propre bloc de mémoire virtualisé, qui peut être mappé sur la RAM, la ROM, les périphériques ou le fichier de page, par exemple).
Pour ce qui est de la pile, cela devrait aider à comprendre que, par défaut, la pile se développe à partir du haut. Donc, si vous faites un push
, le nouveau pointeur de pile sera 0xFFFFFEC
: autrement dit, vous n'essayez pas d'écrire sur l'adresse d'initialisation du BIOS :) Cela signifie bien sûr que les routines d'initialisation du BIOS peuvent utiliser la pile en toute sécurité, avant de la remapper. quelque part plus utile. Dans la programmation traditionnelle, avant que la pagination ne devienne la valeur par défaut, la pile commençait généralement à la fin de la mémoire vive et un "débordement de pile" se produisait lorsque vous commenciez à écraser la mémoire de votre application. La protection de la mémoire a beaucoup changé, mais en général, elle maintient la compatibilité avec les versions antérieures autant que possible. Notez que même le processeur x86-64 le plus moderne peut toujours démarrer MS DOS 5. - ou comment Windows peut toujours exécuter de nombreuses applications DOS qui n'ont aucune idée de la pagination.