Я где-то читал, что (по крайней мере, начиная с Linux v. 2.6) весь код пользовательского пространства размещается по адресу загрузки 0x8048000 в адресном пространстве виртуальной памяти.
Мои собственные наблюдения подтверждают это. Я сделал
cat /proc/......../maps
для нескольких процессов и самого первого раздела программы процесса text
всегда начинается с «0x8048000».
Более того, код запуска библиотеки C и все остальные полезные функции среды выполнения, похоже, отображаются после этого значения по умолчанию.
Это составляет почти 128 МБ адресного пространства, что не так уж много, если учесть, что 0xC0000000 - 0x8048000 по-прежнему составляет почти 3 ГБ адресного пространства для пользовательского пространства.
Итак, мой вопрос: почему?
Мы имеем дело с виртуальными адресами, помехи или совпадения с другими программами исключены по определению принципа работы виртуальной машины.
Существуют ли какие-либо фиксированные/стандартные сопоставления в диапазоне от 0x00000000 до 0x8048000?
Помимо того, что начальный адрес по умолчанию приходится на границу страницы, каково обоснование выбора именно этого числа, а не любого другого значения?
решение1
Признаю, что следующий ответ не очень хорош, но я считаю, что значение 0x8048000 заложено вСпецификация ELF. См. рисунки A.4, A.5 и A.6 в этом документе.Дополнение к архитектуре System V ABI Intel 386также стандартизирует 0x8048000. См. страницу 3-22, рисунок 3-25. 0x804800 предписан как адрес нижнего текстового сегмента/верхний адрес стека. И это само по себе странно, так как стеки обычно устанавливаются в верхних адресах пространства памяти процесса, и Linux не является исключением.
Вы можете заставить компоновщик GNU ld
настроить исполняемый файл ELF так, чтобы ядро сопоставляло его с несколько более низким или более высоким адресом. Метод, позволяющий это сделать, варьируется от версии к версии GCC и ld, поэтому внимательно читайте страницы руководства. Это может означать, что 0x8048000 не вытекает из каких-то аппаратных требований, а скорее из других соображений.