Современный загрузчик программ ОС в основном использует mmap
, а не read
. https://en.wikipedia.org/wiki/Memory-mapped_file#Common_uses говорит:
Пожалуй, наиболее распространенным использованием файла с отображением в памяти является загрузчик процессов в большинстве современных операционных систем (включая Microsoft Windows и Unix-подобные системы).
Это создает частное отображение на основе файла. (https://en.wikipedia.org/wiki/Virtual_memory).
- ... Другими словами, как ОС распознает, что она должна прекратить выполнение инструкции, чтобы избежать перехода на нерелевантный адрес, и как она рассчитывает, на какой странице находится соответствующий адрес?
В этом случае выборка кода вызывает ошибку страницы , как если бы ваш код загружался из части большого статического массива, который еще не был загружен с диска. После возможной загрузки страницы с диска (если она еще не присутствовала в кэше страниц) и обновления таблиц страниц, выполнение возобновляется по адресу, на котором произошел сбой, чтобы повторить инструкцию.
Аппаратное обеспечение виртуальной памяти ЦП («MMU», хотя на самом деле это не отдельная вещь в современном ЦП) обрабатывает обнаружение загрузок / сохранений / выборки кода с не отображенных адресов. (Несопоставленный в соответствии с фактическими таблицами страниц, которые может видеть HW. Когда процесс «логически» отображает некоторую память, но ОС ленится об этом, мы говорим, что память «не подключена» к таблицам страниц, поэтому ошибка страницы перенесет ее в память, если она еще не существует, и свяжет ее с таблицами страниц, чтобы HW мог получить к ней доступ (после пропуска TLB для запуска аппаратного просмотра страницы.)
Если есть какие-либо перемещения символов во время выполнения, также известные как исправления , для учета программы, загружаемой по базовому адресу, отличному от того, для которого она была связана, если ей нужны какие-либо абсолютные адреса в памяти, они могут требует написания страниц кода или других данных, доступных только для чтения, загрязнения страницы виртуальной памяти, чтобы она поддерживалась файлом подкачки вместо исполняемого файла на диске. например если ваш источник C включает int *foo = &bar;
в глобальном масштабе или int &foo = bar;
- Сколько страниц кода ОС копирует в ОЗУ, прежде чем перейти к точке входа в программу?
В загрузчике программы, вероятно, есть некоторая эвристика, чтобы убедиться, что точка входа и, возможно, некоторые другие страницы отображаются перед первой попыткой. Кроме этого IDK, если в коде виртуальной памяти есть какая-либо особая эвристика для исполняемых файлов / библиотек и неисполняемых отображений.