LINUX.ORG.RU

История изменений

Исправление KivApple, (текущая версия) :

Давным давно процессоры Intel были 16 битными. Соответственно, максимально могли адресовать 64 кб ОЗУ. Времена шли и это оказалось мало, но терять обратную совместимость не хотелось. И поэтому Intel придумали костыль - появились так называемые сегментные регистры (тоже 16 бит). Реальный адрес получался сдвигом значения сегментного регистра на 4 бита (фактически умножение на 16) и прибавлением смещения (старого адреса). Таким образом стало возможно использовать 1 мб ОЗУ вместо 64 кб. При этом старые программы про сегментные регистры не знали, ос загружала некоторое дефолтное значение и программа работала с одним сегментом как будто это была вся доступная память.

Компиляторы того времени умели компилировать программу в двух режимах - старом и новом. В первом случае программа делала вид, что не знает ничего о сегментах (работала в рамках того, что дала ей ОС) и поэтому можно было в качестве указателя использовать только 16битное смещение. В новом же режиме программа знала про сегменты и указатели становились 32 бита, потому что хранили две части адреса - сегмент и смещение. Таким образом, если программе было нужно мало памяти, можно было сэкономить на размере указателей, да ещё и получить совместимость с совсем древними процессорами.

Время шло и пришли 32 бита. Смещения в сегментах стали 32 битными, а сами значения сегментных регистров изменили смысл (теперь это не просто старшая часть адреса, а индекс в таблице ОС, которая хранить больше инфы про сегмент). Смысла использовать сегменты для увеличения объёма адресуемой памяти не стало (смещения и так 32 бита, а больше 4 ГБ те процессоры все равно не умели). Так что ни один 32битный компилятор с сегментацией работает не умеет и делает вид, что её нет (не трогает содержимое сегментных регистров и поэтому использует то, что дала ОС). Да и нельзя иначе - теперь значения сегментов это не кусок адреса, а индекс в таблице и только ОС знает зачем какие сегменты нужны. Соответственно, при компиляции в 32 бита нету двух разных режимов.

В 64 битах пошли дальше. Теперь все сегменты имеют базовый адрес 0 и максимальную длину и больше не влияют на преобразования виртуальных адресов в физические вообще. Так что даже теоретически хранить в указателе номер сегмента компилятору стало бессмысленно.

Так что понятие модели памяти в прежнем значении к 32 и 64 битными компиляторам (не только GCC, но и MSVC и любой другой), не применимо вообще. Опция с таким именем влияет совсем на другие вещи и имеет иной смысл.

Твоя лабораторная имеет смысл исключительно в DOS. Среда разработки и компилятор нужны соответствующие.

Исходная версия KivApple, :

Давным давно процессоры Intel были 16 битными. Соответственно, максимально могли адресовать 64 кб ОЗУ. Времена шли и это оказалось мало, но терять обратную совместимость не хотелось. И поэтому Intel придумали костыль - появились так называемые сегментные регистры (тоже 16 бит). Реальный адрес получался сдвигом значения сегментного регистра на 4 бита (фактически умножение на 16) и прибавлением смещения (старого адреса). Таким образом стало возможно использовать 1 мб ОЗУ вместо 64 кб. При этом старые программы про сегментные регистры не знали, ос загружала некоторое дефолтное значение и программа работала с одним сегментом как будто это была вся доступная память.

Компиляторы того времени умели компилировать программу в двух режимах - старом и новом. В первом случае программа делала вид, что не знает ничего о сегментах (работала в рамках того, что дала ей ОС) и поэтому можно было в качестве указателя использовать только 16битное смещение. В новом же режиме программа знала про сегменты и указатели становились 32 бита, потому что хранили две части адреса - сегмент и смещение. Таким образом, если программе было нужно мало памяти, можно было сэкономить на размере указателей, да ещё и получить совместимость с совсем древними процессорами.

Время шло и пришли 32 бита. Смещения в сегментах стали 32 битными, а сами значения сегментных регистров изменили смысл (теперь это не просто старшая часть адреса, а индекс в таблице ОС, которая хранить больше инфы про сегмент). Смысла использовать сегменты для увеличения объёма адресуемой памяти не стало (смещения и так 32 бита, а больше 4 ГБ те процессоры все равно не умели). Так что ни один 32битный компилятор с сегментацией работает не умеет и делает вид, что её нет (не трогает содержимое сегментных регистров и поэтому использует то, что дала ОС). Да и нельзя иначе - теперь значения сегментов это не кусок адреса, а индекс в таблице и только ОС знает зачем какие сегменты нужны. Соответственно, при компиляции в 32 бита нету двух разных режимов.

В 64 битах пошли дальше. Теперь все сегменты имеют базовый адрес 0 и максимальную длину и больше не влияют на преобразования виртуальных адресов в физические вообще. Так что даже теоретически хранить в указателе номер сегмента компилятору стало бессмысленно.

Так что понятие модели памяти в прежнем значении к 32 и 64 битными компиляторам (не только GCC, но и MSVC и любой другой), не применимо вообще. Опция с таким именем влияет совсем на другие вещи и имеет иной смысл.

Твоя лабораторная имеет смысл исключительно в DOS.