Все они имеют базовый адрес 0, а предел - 4G т.е. адресуют всё виртуальное адресное пространство памяти. ся фиксированными. Если кто и оперирует сегментными регистрами - так это ОС.
Хорошо, у нас есть, например, 512Мб физической памяти, значит адресоваться оно может от 0...536870911 линейно, первая грузится ОС из реального режима, создаёт GDT, и описывает свои дескрипторы кода и данных.
Нет, адресоваться в виртуальной памяти будет от 0 до 4Гбайт, а эта виртуальная память уже будет отображаться на физическую. В принципе в этом и есть суть виртуальной памяти - реально памяти может быть много меньше, но создаётся иллюзия, что ей столько, сколько надо. Например это делается при помощи свопинга (при недостаче страниц памяти занятые страницы записываются на диск и объявляются свободными и при необходимости данных, которые раньше были в них необходимо записать их текущее содержимое на диск и опять прочитать, что там было до того).
Предположим, что первый будет иметь базу 0, лимит 4G, фактически займёт 40Мб пространства, тогда у второго база уже 0 быть не может (база, вроде, считается от физического "0"), тогда база второго будет соответствовать концу первого.
Нет у всех база 0, лимит 4Гбайт. мало того, дескрипторы сегментов для всех прикладных задач общие. Т.е. не будет для каждой задачи своих дескрипторов, все они будут общие, а разделение, что этот участок памяти относится к одной задаче, этот - к другой, а этот - вообще к ОС уже делается на основании страничной адресации.
Правильно ли я понимаю: мы считаем участок flat от 0 до лимита, но физически это фрагмент от 0+база, до 0+база+лимит? Любая программа, включая загрузчик, запрашивает себе дескрипторы у ОС. Когда грузится DLL, то она тоже получает свои сегменты, в которых и выполняется...
Думаю, что не запрашивает, как я сказал - дескрипторы сегментов используются очень ограниченно.
С чего, собственно, вопрос возник: такое чувство, что, когда пишешь, например:
; NASM
call [ShowMessageA]
то мы совершаем:
call NEAR [32бит смещение на некую функцию внутри кода нашей программы]
а там:
call FAR [16:32 поле полного адреса, которое формируется с нулями, а заполняется на стадии загрузки DLL]
Возможно даже в "а там:" не call FAR [16:32], а int 2fh (если не путаю), а то и SYSCALL - поход в ОС.
да и там, где call NEAR [32], зависит от типа компоновки, при статической - там будет обычный адрес библиотечной функции, а при динамической - действительно что-то типа 0, и запись в спец-таблице, что этот 0 надо заменить на адрес такой-то функции, которое потом загрузчиком динамических библиотек будет заменено на адрес реальной функции, когда он подгрузит библиотеку и выяснит, по какому адресу в этой библиотеке находится необходимая функция.
Сущность никак не просеку, может посоветуете почитать толковый труд.
Сорри, другого раздела не нашёл, однако, пользователи ассемблера, обычно, ближе у сути реальных процессов) Спасибо.
в принципе - любую книгу по теории построения операционных систем - просто, чтобы представлять как вообще это всё обычно строится, а потом уже переходить к частностям. Можно почитать Танненбаума про общую теорию, Роберта Лава про Linux, Вахалию про построение ОС Unix и Соломона и Руссиновича про Windows.