«Целостность данных в физической памяти можно было сохранить с помощью алгоритма или подобного, не позволяющего процессам получать доступ или изменять участки памяти, к которым уже обращались другие процессы».
Короткий ответ: невозможно разработать эффективный алгоритм, как предлагается, чтобы соответствовать тому же уровню производительности с логическим адресом.
Проблема с этим алгоритмом заключается в том, как вы собираетесь перехватывать каждый процесс доступ к памяти? Без перехвата доступа к памяти невозможно проверить, имеет ли процесс права доступа к определенной области памяти. Если мы действительно собираемся реализовать эти алгоритмы, есть способы перехватить доступ к памяти без использования логического адреса, предоставляемого MMU (блок управления памятью) на современных процессорах (предположим, у вас есть процессор без MMU). Однако эти методы не будут такими эффективными, как использование MMU. Если в вашем процессоре есть MMU, хотя трансляция логического адреса будет неизбежной, вы можете настроить физическую память один к одному.
Один из способов перехватить доступ к памяти без MMU - это вставить команду прерывания ядра перед каждой инструкцией доступа к памяти в программе. Поскольку мы не можем доверять программе пользовательского уровня, такую работу нельзя делегировать компилятору. Таким образом, вы можете написать ОС, которая будет выполнять эту работу до того, как загрузит программу в память. Эта ОС будет сканировать двоичный файл вашей программы и вставлять команду прерывания ядра перед каждым обращением к памяти. Таким образом, ядро может проверить, следует ли предоставить доступ к памяти. Однако такой подход значительно снижает производительность вашей системы, поскольку каждый доступ к памяти, законный или нет, будет попадать в ядро. А захват в ядро включает переключение контекста, которое занимает много циклов процессора.
Можем ли мы сделать лучше? Как насчет статического c анализа доступа наших программ к памяти перед загрузкой их в память, чтобы мы вставляли ловушку только перед незаконным доступом к памяти? Однако у процессов нет предопределенного порядка выполнения. Допустим, у вас есть программы A и B. Они обе пытаются получить доступ к одной и той же области памяти. Тогда кто должен получить это с помощью нашего статического c анализа? Мы могли случайным образом назначить одного из них. Скажем, мы назначаем B. Тогда как мы узнаем, когда B будет сделано с этой памятью, чтобы мы могли передать A, чтобы он мог продолжить? Допустим, B использует этот регион для хранения глобальной переменной, к которой обращались несколько раз на протяжении ее жизненного цикла. Дождемся ли мы завершения B, чтобы передать эту область A? Что, если B никогда не закончится?
Более того, статический c анализ доступа к памяти был бы невозможен при наличии динамического c распределения памяти. Если программа A или B пытается выделить область памяти, размер которой зависит от ввода пользователя, тогда ОС или наш инструмент анализа stati c не может заранее знать, где и насколько велика область. И поэтому мы вообще не сможем провести анализ.
Таким образом, мы должны возвращаться к ловушке при каждом доступе к памяти и определять, является ли доступ законным во время выполнения. Звучит знакомо? Это функция MMU или логического адреса. Однако с логическим адресом ловушка возникает тогда и только тогда, когда вместо каждого доступа к памяти произошел незаконный доступ.