Premièrement, cela n'a rien à voir avec la RAM, vraiment. Nous parlons de espace adresse ici - même si vous n'avez que 16 Mio de mémoire, vous disposez toujours de la totalité des 32 bits de l'espace d'adressage sur un CPU 32 bits.
Cela répond déjà à votre première question : à l'époque où ce système a été conçu, les PC du monde réel étaient loin de disposer de la totalité des 4 Go de mémoire ; ils étaient plutôt de l'ordre de 1 à 16 Mio de mémoire. L'espace d'adressage était, à toutes fins utiles, libre.
Maintenant, pourquoi 0xFFFFFFF0 exactement ? Le processeur ne sait pas combien il reste du BIOS. Certains BIOS peuvent ne prendre que quelques kilo-octets, tandis que d'autres peuvent prendre des méga-octets complets de mémoire - et je ne parle même pas des différentes RAM optionnelles. Le CPU doit être câblé à une certaine adresse de départ - il n'y a pas de configuration possible du CPU. 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 autant - mais cela n'a rien de spécial, de nombreux périphériques nécessitent leur propre plage d'espace d'adressage). Sur un processeur 32 bits, cette adresse vous donne 16 octets complets pour effectuer l'initialisation de base - ce qui est suffisant pour configurer vos segments et, si nécessaire, le mode d'adressage (rappelez-vous, x86 démarre en mode réel 16 bits - l'espace d'adressage n'est pas plat) et effectuer un saut vers le fichier réel démarrer la "procédure". À ce stade, vous n'utilisez pas du tout la RAM - il s'agit uniquement de 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 16 bits peut accéder à l'adresse 0xFFFFFFF0 ? Bien sûr, il y a des segments, donc vous avez un espace d'adresse de 20 bits, mais ce n'est toujours pas suffisant. Il existe une astuce : les 12 bits de poids fort de l'adresse sont activés jusqu'à ce que vous exécutiez votre premier saut long, ce qui vous donne accès à l'espace d'adressage supérieur (tout en rejetant l'accès à tout ce qui est inférieur à 0xFFF00000 - jusqu'à ce que vous exécutiez un saut long).
Ce sont toutes ces choses qui sont le plus souvent cachées aux programmeurs (sans parler des utilisateurs) sur les systèmes d'exploitation modernes. Vous n'avez généralement pas accès à des éléments de si bas niveau - certaines choses sont déjà irrécupérables (vous ne pouvez pas changer de mode d'unité centrale bon gré mal gré), d'autres sont exclusivement gérées par le noyau du système d'exploitation.
Une vue plus agréable vient donc du codage à l'ancienne sur MS DOS. Un autre exemple typique de mémoire de périphérique directement mappée à l'espace d'adressage est l'accès direct à la mémoire vidéo. Par exemple, si vous voulez écrire du texte sur l'écran rapide, vous écrivez directement à l'adresse B800:0000
(plus le décalage - en mode texte 80x25, cela signifiait (y * 80 + x) * 2
si ma mémoire est bonne - 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
(généralement, 320x200 à 8 bits par pixel). Pour faire quelque chose de performant, il fallait généralement se plonger dans les manuels des périphériques pour savoir comment y accéder directement.
Cela survit à ce jour - c'est juste caché. Sous Windows, vous pouvez voir les adresses mémoire mappées aux périphériques dans le Gestionnaire de périphériques - il suffit d'ouvrir les propriétés de quelque chose comme votre carte réseau, d'aller dans l'onglet Ressources - tous les éléments de la plage de mémoire sont des mappages de la mémoire du périphérique à 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 de 2 GiB (plus tard 3 GiB) - encore une fois, pour minimiser les conflits avec la mémoire utilisable par l'utilisateur, bien que ce ne soit pas vraiment un problème avec la mémoire virtuelle (les applications ne s'approchent pas de la marque de 2 GiB). réel, matériel espace d'adressage - ils ont leur propre morceau de mémoire virtualisé, qui peut être mappé à la RAM, à la ROM, aux périphériques ou au fichier de page, par exemple).
En ce qui concerne la pile, il faut 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
- en d'autres termes, vous n'essayez pas d'écrire à l'adresse init du BIOS :) Ce qui signifie bien sûr que les routines d'initialisation du BIOS peuvent utiliser la pile en toute sécurité, avant de la remapper à un endroit plus utile. Dans la programmation à l'ancienne, avant que la pagination ne devienne le défaut de facto, la pile commençait généralement à la fin de la RAM, et le "débordement de la pile" se produisait lorsque vous commenciez à écraser la mémoire de votre application. La protection de la mémoire a changé beaucoup de choses, mais en général, elle maintient la compatibilité ascendante autant que possible - notez comment même le plus moderne des CPU x86-64 peut Toujours démarrer MS DOS 5 - ou comment Windows peut encore exécuter de nombreuses applications DOS qui n'ont aucune idée de la pagination.