Mirmik писал(а):
Хм... Насколько я понимаю, при компиляции, обычно код исполняемого файла создаётся без учета того, где конкретно в памяти будет висеть исполняемый код, потому что смещение будет отрабатано через MMU.
Но без MMU - критично, куда в память ляжет код. Разве не так?
Самый простой подход -- собирать исполняемый образ под работу с конкретного адреса памяти и в дальнейшем загружать и выполнять именно по этому адресу. Достаточно широко применялся на малых машинах, где ресурсы сильно ограничены; применяется и сейчас во встраиваемых системах. Параллельное выполнение нескольких программ по-прежнему возможно, но для этого они должны либо загружаться в разные области памяти (т.е. каждая строиться для своего адреса загрузки -- для встраиваемой системы это самый разумный подход, поскольку набор выполняющихся программ там заведомо известен), либо целиком "кочевать" из ОЗУ в файл подкачки и обратно. Последний вариант, несмотря на кажущуюся неэффективность, в определённых ситуациях вполне себе нормальный: например, если надо выполнять всего две задачи, одна из которых взаимодействует с пользователем (и 99% времени проводит, ожидая реакции пользователя), а вторая -- что-то считает.
Другой подход -- сохранять в исполняемом файле информацию, необходимую для его перемещения, и при запуске загружать в имеющуюся область памяти, параллельно настраивая загружаемый код на конкретное местоположение. Понятно, что этот способ тоже может комбинироваться с выгрузкой в файл подкачки. Он использовался в достаточно крупных системах, не имеющих MMU. Сейчас, пожалуй, не используется, поскольку в тех применениях, где могут выполняться произвольные наборы программ (на обычных компьютерах), процессоры всегда имеют MMU, а там, где набор программ строго фиксирован, эффективней первый способ.