Pourquoi est-ce que l'ELFE l'exécution de point d'entrée d'adresse virtuelle de la forme 0x80xxxxx et pas zéro 0x0?
Lorsqu'il est exécuté, le programme va commencer à courir à partir d'adressage virtuel 0x80482c0. Cette adresse n'est pas le point à notre main()
procédure, mais à une procédure nommée _start
qui est créé par l'éditeur de liens.
Mon Google recherche à ce jour m'a conduit à certains (vague) historique des spéculations comme ceci:
Il est du folklore que 0x08048000 était une fois STACK_TOP (qui est, la pile grandit vers le bas à partir de près de 0x08048000 vers 0) sur un port de *NIX pour i386 et qui a été promulguée par un groupe de Santa Cruz, en Californie. C'est alors que 128 MO de RAM était cher, et 4 go de RAM était impensable.
Quelqu'un peut confirmer ou nier cela?
0x08048000
jamais été STACK_TOP
, c'était très il y a longtemps. Ce dernier est TASK_SIZE
tout le chemin à 2.0.40.OriginalL'auteur Michael L. | 2010-02-02
Vous devez vous connecter pour publier un commentaire.
Comme Mads a souligné, pour la plupart des captures accède par le biais de pointeurs nuls, les systèmes de type Unix ont tendance à faire de la page à l'adresse zéro "actifs". Ainsi, accède immédiatement déclencher un PROCESSEUR exception, en d'autres termes, une erreur de segmentation. C'est bien mieux que de laisser l'application aller voyous. L'exception vecteur de la table, cependant, peut être à n'importe quelle adresse, au moins sur des processeurs x86 (il y a un registre spécial pour que, chargé de la
lidt
opcode).Le point de départ de l'adresse fait partie d'un ensemble de conventions qui décrivent le fonctionnement de la mémoire. L'éditeur de liens, quand il produit un binaire exécutable, doit connaître ces conventions, de sorte qu'ils ne sont pas susceptibles de changer. En gros, pour Linux, la disposition de la mémoire des conventions héritées de l'premières versions de Linux, au début des années 90. Un processus doit avoir accès à plusieurs domaines:
brk()
etsbrk()
appels système.mmap()
appels système, y compris la bibliothèque partagée de chargement.De nos jours, le tas, où
malloc()
va, est soutenu parmmap()
appels d'obtenir des morceaux de la mémoire à n'importe quelle adresse le noyau, le juge approprié. Mais en des temps plus anciens, Linux a été comme les précédents systèmes de type Unix, et son tas tenu une grande place dans l'un sans interruption morceau, qui peut se développer vers l'augmentation des adresses. Donc, ce qui était de la convention, il avait des trucs du code et de la pile vers le bas les adresses, et de donner à chaque partie de l'adresse de l'espace après un point sur le segment.Mais il y a aussi la pile, qui est généralement assez faible, mais pourrait croître de façon spectaculaire dans certaines occasions. La pile grandit vers le bas, et lorsque la pile est pleine, nous voulons vraiment que le processus prévisible crash plutôt que de remplacer certaines données. Donc, il y avait une grande zone de la pile, avec, à l'extrémité inférieure de cette zone, un unmapped page. Et voilà! Il y a un unmapped page à l'adresse zéro, pour attraper pointeur null déréférence. Par conséquent, il a été défini que la pile d'obtenir les premiers 128 MO d'espace d'adressage, à l'exception de la première page. Cela signifie que le code a pour aller après les 128 MO, à une adresse semblable à 0x080xxxxx.
Comme il le souligne, "perdre" 128 MO d'espace d'adressage était pas une grosse affaire parce que l'adresse de l'espace est très grand par rapport à ce qui pourrait être réellement utilisé. À ce moment, le noyau Linux a été de limiter l'espace d'adressage d'un processus unique de 1 GO, sur un maximum de 4 GO autorisé par le matériel, et qui n'a pas été considéré comme être un gros problème.
OriginalL'auteur Thomas Pornin
Pourquoi ne pas commencer à l'adresse 0x0? Il y a au moins deux raisons à cela:
Comme pour le point d'entrée
_start
vsmain
:Si vous link contre le runtime C (le C standard des bibliothèques), la bibliothèque encapsule la fonction nommée
main
, de sorte qu'il est possible d'initialiser l'environnement avant demain
est appelé. Sur Linux, ce sont les argc et argv paramètres de l'application, le env variables, et probablement quelques primitives de synchronisation et de serrures. Elle fait également en sorte que le retour de la principale passe sur le code d'état, et appelle la_exit
fonction, qui termine le processus._GLOBAL_OFFSET_TABLE_
également des points dans le0x200XXX
gamme de Binutils 2.24.OriginalL'auteur