Здравствуйте, Вот начал изучать ассемблер. Столкнулся с понятием сегмента. Начал искать чего это такое и с чем едят. Нашел в википедии след. информацию: что в 8086-м проце была 20-ти битная шина данных, поэт. адресовать можно было 1Мбайт памяти. Поскольку регистры оставались 16-ти битными то адресация происходила путем сложения содержимого одного из сегментных регистров (16 бит), умноженного на 16, с содержимым указательного регистра. В первом регистре содержался номер сегмента, во втором смещение. И далее сказано что, память разделяется на сегменты, размером 64 Кбайт каждый и начинающиеся с адреса, кратного 16 (граница параграфа); память в 1 Мбайт разделялась, таким образом, на 16 сегментов. http://ru.wikipedia.org/wiki/Intel_8086 Не понятно почему сегментов получилось 16, ведь если сегментный регистр 16-ти битный тогда получается количество сегментов 65535 и поскольку объем регистра со смещением тоже 16 бит то объем сегмента 64 кбайта и начинаются они каждый через 16 бит после начала предыдущего,т.е. происходит взаимоналожение и в итоге получается что одна и та же ячейка памяти имеет кучу адресов. Растолкуйте пожалуйста.
Сегменты могут перекрываться. Линейный 20-битный адрес 12345 можно записать как 1234:0005 или же 1230:0045 или 1200:0345 или 1000:2345 или 1100:1345 ну и так далее. Не перекрывающихся областей по 64к действительно в мегабайт укладывается 16 штук. Но различных значений сегментного регистра - 65536 штук от 0000 до FFFF.
наверное так 2^20 - 1 = 1 048 575 байт возможно адрессовать в реальном режиме 16 разрядный регистр сможет адрессовать только 2^16 - 1 = 65 535 байт чтобы адрессовать всю память нужно 2^20 / 2^16 = 2^4 сегментов по 65 535 байт все остальные адреса сегментов избыточны и используются для удобства адрессации
ohne Почему -1? Кстати говоря, адресация сегмент-смещение покрывает чуть больше, чем 1 мегабайт. А точнее 1 мегабайт + 65536 - 16 байт. Эти "лишние" 65520 байт расширенной называются High Memory Area (HMA). Когда памяти была 1мб, то 20битная адресация закольцовывала эти адреса на первые 65520 байт. Потом память стала больше, а адресная линия A20 ради совместимости со старыми программами осталась отключена. Для использования HMA ее надо включить.
Если можно поясните что значит: "Не перекрывающихся областей по 64к действительно в мегабайт укладывается 16 штук. Но различных значений сегментного регистра - 65536 штук от 0000 до FFFF." Если я правильно понял должны быть некие правила адресации ну типа в регистр сегмента данные заносятся только в старшие 4 бита, а в регистр со смещением во все - тогда адреса на перекрестятся.
Ну а что непонятного? Адресация сегмент-смещение не уникальна. Одну ячейку можно адресовать целым списком виртуальных адресов.
нет каких либо подобных правил есть сегмент есть смещение есть линейный адрес и есть соответствующие ему логические адреса чтобы покрыть всю память нужно использовать минимум 16 сегментов тобишь этих о которых написали выше
ohne Боюсь, может флейм, но... с логическими было правильно. Виртуальных адресов нету в реальном режиме. К тому же понятие виртуального адреса определяется ОС, а к процессорам Intel вообще не имеет отношения.
т.е. если я правильно понял для того чтобы сегменты не покрывались выдача их производится автоматически? и еще маленький вопрос: если я директивой SEGMENT определяю новый сегмент то что означает атрибут выравнивания сегмента, т.е. смысл я понимаю с какого "места" начнется сегмент, а на что это влияет нет
_roman_ Что значит "выдача их производится автоматически"? Сегменты перекрываются или нет в зависимости от того, что программист загрузит в сегментные регистры -- т.е. это полностью ответственность человека. Автоматически не происходит _ничего_. Директива SEGMENT сообщает транслятору, что далее идут код и данные, которые должны находиться в одном логическом сегменте, т.е. следовать подряд друг за другом и перемещаться как единое целое (перемещение происходит при загрузке программы в память, ведь во время трансляции адреса загрузки ещё не известны). У логических сегментов есть атрибуты, которые управляют работой транслятора и компоновщика. Один из этих атрибутов -- выравнивание; он показывает, какой величине должен быть кратен адрес первого байта сегмента после загрузки в память. Это может повысить производительность, например (чтение или запись слова из памяти может быть выполнено быстрее, если это слово размещается на границе слова, т.е. его адрес чётный; двойного слова -- если адрес кратен 4 и т.д.). Есть ещё атрибут, управляющий комбинированием одноимённых сегментов. Когда пишется большая программа, она состоит из нескольких исходных файлов, в каждом из которых обычно присутствуют сегменты с одинаковыми именами (грубо говоря, "код" и "данные"). После трансляции такой программы получается несколько объектных файлов -- по одному на каждый исходный. Затем эти объектные файлы собираются в исполняемую программу (обычно exe-файл) с помощью компоновщика. Вот ему-то и нужна информация о том, как комбинировать одноимённые сегменты: то ли "складывать" их, когда на выходе получается один сегмент с длиной, равной сумме длин сегментов из всех исходных (а значит, и объектных) файлов; то ли "перекрывать" сегменты, когда они накладываются один на другой, давая в результате сегмент с длиной, равной длине самого крупного из исходных сегментов.