Вопрос про память, адресацию и режимы работы проца...

Тема в разделе "WASM.BEGINNERS", создана пользователем _roman_, 3 янв 2010.

  1. _roman_

    _roman_ New Member

    Публикаций:
    0
    Регистрация:
    3 янв 2010
    Сообщения:
    3
    Здравствуйте,
    Вот начал изучать ассемблер. Столкнулся с понятием сегмента. Начал искать чего это такое и с чем едят. Нашел в википедии след. информацию: что в 8086-м проце была 20-ти битная шина данных, поэт. адресовать можно было 1Мбайт памяти. Поскольку регистры оставались 16-ти битными то адресация происходила путем сложения содержимого одного из сегментных регистров (16 бит), умноженного на 16, с содержимым указательного регистра. В первом регистре содержался номер сегмента, во втором смещение. И далее сказано что, память разделяется на сегменты, размером 64 Кбайт каждый и начинающиеся с адреса, кратного 16 (граница параграфа); память в 1 Мбайт разделялась, таким образом, на 16 сегментов.
    http://ru.wikipedia.org/wiki/Intel_8086
    Не понятно почему сегментов получилось 16, ведь если сегментный регистр 16-ти битный тогда получается количество сегментов 65535 и поскольку объем регистра со смещением тоже 16 бит то объем сегмента 64 кбайта и начинаются они каждый через 16 бит после начала предыдущего,т.е. происходит взаимоналожение и в итоге получается что одна и та же ячейка памяти имеет кучу адресов.
    Растолкуйте пожалуйста.
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Сегменты могут перекрываться. Линейный 20-битный адрес 12345 можно записать как 1234:0005 или же 1230:0045 или 1200:0345 или 1000:2345 или 1100:1345 ну и так далее.
    Не перекрывающихся областей по 64к действительно в мегабайт укладывается 16 штук. Но различных значений сегментного регистра - 65536 штук от 0000 до FFFF.
     
  3. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    наверное так

    2^20 - 1 = 1 048 575 байт возможно адрессовать в реальном режиме
    16 разрядный регистр сможет адрессовать только 2^16 - 1 = 65 535 байт
    чтобы адрессовать всю память нужно 2^20 / 2^16 = 2^4 сегментов по 65 535 байт
    все остальные адреса сегментов избыточны и используются для удобства адрессации
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ohne
    Почему -1?

    Кстати говоря, адресация сегмент-смещение покрывает чуть больше, чем 1 мегабайт. А точнее 1 мегабайт + 65536 - 16 байт. Эти "лишние" 65520 байт расширенной называются High Memory Area (HMA). Когда памяти была 1мб, то 20битная адресация закольцовывала эти адреса на первые 65520 байт. Потом память стала больше, а адресная линия A20 ради совместимости со старыми программами осталась отключена. Для использования HMA ее надо включить.
     
  5. _roman_

    _roman_ New Member

    Публикаций:
    0
    Регистрация:
    3 янв 2010
    Сообщения:
    3
    Если можно поясните что значит: "Не перекрывающихся областей по 64к действительно в мегабайт укладывается 16 штук. Но различных значений сегментного регистра - 65536 штук от 0000 до FFFF."
    Если я правильно понял должны быть некие правила адресации ну типа в регистр сегмента данные заносятся только в старшие 4 бита, а в регистр со смещением во все - тогда адреса на перекрестятся.
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну а что непонятного? Адресация сегмент-смещение не уникальна. Одну ячейку можно адресовать целым списком виртуальных адресов.
     
  7. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    нет каких либо подобных правил
    есть сегмент есть смещение
    есть линейный адрес и есть соответствующие ему логические адреса
    чтобы покрыть всю память нужно использовать минимум 16 сегментов тобишь этих
    о которых написали выше
     
  8. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    * логические == виртуальные
     
  9. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    ohne
    Боюсь, может флейм, но... с логическими было правильно. :) Виртуальных адресов нету в реальном режиме. К тому же понятие виртуального адреса определяется ОС, а к процессорам Intel вообще не имеет отношения.
     
  10. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    *может начаться флейм
     
  11. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    разницы нет
     
  12. _roman_

    _roman_ New Member

    Публикаций:
    0
    Регистрация:
    3 янв 2010
    Сообщения:
    3
    т.е. если я правильно понял для того чтобы сегменты не покрывались выдача их производится автоматически?
    и еще маленький вопрос: если я директивой SEGMENT определяю новый сегмент то что означает атрибут выравнивания сегмента, т.е. смысл я понимаю с какого "места" начнется сегмент, а на что это влияет нет
     
  13. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    _roman_
    Что значит "выдача их производится автоматически"? Сегменты перекрываются или нет в зависимости от того, что программист загрузит в сегментные регистры -- т.е. это полностью ответственность человека. Автоматически не происходит _ничего_.

    Директива SEGMENT сообщает транслятору, что далее идут код и данные, которые должны находиться в одном логическом сегменте, т.е. следовать подряд друг за другом и перемещаться как единое целое (перемещение происходит при загрузке программы в память, ведь во время трансляции адреса загрузки ещё не известны). У логических сегментов есть атрибуты, которые управляют работой транслятора и компоновщика. Один из этих атрибутов -- выравнивание; он показывает, какой величине должен быть кратен адрес первого байта сегмента после загрузки в память. Это может повысить производительность, например (чтение или запись слова из памяти может быть выполнено быстрее, если это слово размещается на границе слова, т.е. его адрес чётный; двойного слова -- если адрес кратен 4 и т.д.). Есть ещё атрибут, управляющий комбинированием одноимённых сегментов. Когда пишется большая программа, она состоит из нескольких исходных файлов, в каждом из которых обычно присутствуют сегменты с одинаковыми именами (грубо говоря, "код" и "данные"). После трансляции такой программы получается несколько объектных файлов -- по одному на каждый исходный. Затем эти объектные файлы собираются в исполняемую программу (обычно exe-файл) с помощью компоновщика. Вот ему-то и нужна информация о том, как комбинировать одноимённые сегменты: то ли "складывать" их, когда на выходе получается один сегмент с длиной, равной сумме длин сегментов из всех исходных (а значит, и объектных) файлов; то ли "перекрывать" сегменты, когда они накладываются один на другой, давая в результате сегмент с длиной, равной длине самого крупного из исходных сегментов.