Итог: некоторые технические ограничения, которые amd64
имеет при использовании больших адресов, предлагают выделить нижнее 2GiB
адресного пространства для кода и данных для повышения эффективности. Таким образом, стек был перемещен из этого диапазона.
В i386
ABI
- стека находится перед кодом, растет с чуть менее
0x8048000
вниз. Что обеспечивает «чуть более 128 МБ для стека и около 2 ГБ для текста и данных» (стр. 3-22).
- Динамические сегменты начинаются в
0x80000000
(2GiB),
- и ядро занимает «зарезервированной области» на вершине которой спецификация позволяет достигать
1GiB
, начиная по меньшей мере 0xC0000000
(стр. 3-21) (which is what it typically does).
- Основная программа не обязательно должна быть независимой от положения.
- Реализация не требуется для доступа к нулевому указателю (стр. 3-21), но разумно ожидать, что для этого будет зарезервировано некоторое пространство стека выше
128MiB
(которое равно 288KiB
).
amd64
(whose ABI формулируется в виде поправки к i386
один (стр. 9)) имеет значительно больший (48-бит) адресное пространство, но большинство команд принимают только 32-разрядные непосредственные операнды (которые включают в себя прямые адреса и смещения в инструкциях перехода), требуя большей работы и менее эффективного кода (особенно при учете взаимозависимости инструкций) для обработки больших значений. Меры по устранению этих ограничений обобщены авторами, введя несколько «кодовых моделей», которые они рекомендуют использовать для «разрешить компилятору генерировать лучший код». (стр. 33)
- В частности, первый из них, "Малый кода модель", предлагает использовать адрес «в диапазоне от 0 до 2 -2 -1 или от
0x00000000
до 0x7effffff
", который позволяет использовать очень эффективные относительные ссылки и итерацию массива.Это 1.98GiB
, что более чем достаточно для многих программ.
- «Средняя модель кода» основана на предыдущем, разделяет данные в «быструю» часть под указанной границей и «более медленную» оставшуюся часть, для которой требуется специальная инструкция для доступа. Пока код остается под границей.
- И только «большая» модель не делает предположений о размерах, требуя компилятора «использовать инструкцию
movabs
, как в модели кода , даже для обработки адресов внутри текстового раздела. необходим при ветвлении на адреса, чья смещение от текущего указателя инструкции неизвестно. " Они продолжают предлагать разбиение базы кода на несколько разделяемых библиотек, поскольку эти меры не применяются для относительных ссылок с смещениями, которые, как известно, находятся в пределах границ (как указано в «Модели с независимым кодом с малой позицией»).
Таким образом, стек был перенесен под общей библиотекой пространства (0x80000000000
, 128GiB
), потому что его адрес никогда не Непосредственные операндов, всегда ссылаются либо косвенно или с lea
/mov
из другой ссылки, таким образом, только относительное смещение ограничения.
Приведенное выше объясняет, почему адрес загрузки был перенесен на нижний адрес. Теперь, почему он был перенесен точно в 0x400000
(4MiB
)? Вот, я пришел пустой так, подводя итоги того, что я прочитал в спецификации ABI, я могу только догадываться, что он чувствовал себя «впору»:
- Это достаточно большой, чтобы поймать любую вероятную неправильную структуру смещения, что позволяет больше данных, которые
amd64
работает, но достаточно мал, чтобы не тратить большую часть ценных сообщений 2GiB
адресного пространства.
- Он равен самому большому практическому размеру страницы на сегодняшний день и является кратным всем другим размерам виртуальной памяти, о которых можно думать.
Обратите внимание, что фактические x32 версии Linux были отклонения от этой схемы more и more как время идет. Но мы говорим о спецификации ABI здесь, так как форма amd64
формально основана на ней, а не на любом производном макете (см. Его пункт для цитирования).
https://www.uclibc.org/docs/psABI-x86_64.pdf - это последняя версия (0.99.7), [согласно WDD OSDev] (http://wiki.osdev.org/System_V_ABI# Документы). –
0x400000 - это 4MiB, поэтому это может иметь какое-то отношение к огромной поддержке страниц. В разделе 3.3.3 разрешен только размер страницы до 64 килобайт. –
@ivan_pozdeev: https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI имеет ссылки на PDF-файлы, созданные из версии Git HEAD источника LaTeX. Таблицы страниц x86-64 могут использовать огромные страницы размером 2 МБ (и даже 1GiB), а Linux делает это прозрачно/оппортунистически для анонимной памяти, но не для файлового резервного копирования. Я предполагаю, что 4MB достаточно далеко от 0, что индексированный NULL-указатель deref обычно не будет индексироваться на допустимые страницы. Хе-хе, я вижу, ты сказал то же самое в своем ответе. –