Помогите начать

Тема в разделе "WASM.BEGINNERS", создана пользователем sid, 2 дек 2007.

  1. sid

    sid New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2007
    Сообщения:
    6
    Изучаю asm для DOS. Читаю про память и не понял. Вот фрагмент из книг:

    Действительно, максимальное значение сегментного адреса составляет FFFFh, или 64К-1, из чего следует, что максимальное значение начального адреса сегмента в памяти равно FFFF0h, или 1 Мбайт - 16. Если, однако, учесть, что к начальному адресу сегмента можно добавить любое смещение в диапазоне от 0 до FFFFh, то адрес последнего адресуемого байта окажется равен 10FFEFh, что соответствует величине 1 Мбайт + 64 Кбайт - 17.

    Или вот:

    В качестве примера адресации, допустим, что регистр
    сегмента данных содержит шест. 045F и некоторая команда
    обращается к ячейке памяти внутри сегмента данных со
    смещением 0032. Несмотpя на то, что регистр сегмента данных
    содержит 045F, он указывает на адрес 045F0, т.е. на границе
    параграфа. Действительный aдрес памяти поэтому будет
    следующий:

    Адрес в DS: 045F0
    Смещение: 0032
    Реальный адрес: 04622

    Объясните пожалуйста, откуда берется этот 0 в FFFF ?
    Что значит на границе параграфа?
    И почему все время пишут число - 1 ? Т.Е. почему мы отнимаем 1 ?
    Вобщем прошу Вас объяснить, как работает процессор с памятью в DOS, чтобы это можно было представить в голове.
    ЗАранее спасибо!
     
  2. Ivan_assm

    Ivan_assm New Member

    Публикаций:
    0
    Регистрация:
    5 ноя 2007
    Сообщения:
    132
    Адрес:
    Везде и нигде
    почитатй статьи: "введение в машинный код" и "Программирование на Ассемблере под DOS"...там понятнее изложено)))
    статьи здесь на wasm'е есть в разделе "Неофиту"
     
  3. JAPH

    JAPH New Member

    Публикаций:
    0
    Регистрация:
    23 июн 2007
    Сообщения:
    124
    DOS-программа работает с логическим адресом, состоящим из двух компонент - сегмент:смещение, например, DS:BX. Обе компоненты - 16разрядные числа, поэтому диапазон их изменения 0000h..FFFFh, FFFFh=10000h-1=64K-1. Физический адрес, т.е. ячейка памяти, к которой происходит обращение, вычисляется как 10h*сегмент + смещение.
    Если сегмент фиксировать, т.е. изменять только значение смещения, получаем диапазон логических адресов сегмент:0000h .. сегмент:FFFFh, т.е. сегмент начинается по логическому адресу сегмент:0000h, соответствующему физическому адресу сегмент*10h. Из-за множителя 10h говорят, что сегмент начинается на границе параграфа, то есть физический адрес начала сегмента кратен размеру параграфа, т.е. 16 байт.
     
  4. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    sid
    Сначала про это. В микропроцессоре 8088, на котором был сделан первый IBM PC, было всего 20 адресных линий (т.е. разрядность физического адреса, выдаваемого в память, всегда составляла 20 бит). Как уже объяснил JAPH, физический адрес вычисляется из логического по формуле: 10h*сегмент + смещение. Математически при этом действительно можно пересечь границу 20 битов, как сказано в процитированном Вами тексте ("адрес последнего адресуемого байта окажется равен 10FFEFh"). Однако, поскольку адресных линий было всего 20, старший бит просто-напросто отбрасывался, т.е. максимальный физический адрес был 0FFFFFh (все 20 битов, равных 1). Позднее, когда появился микропроцессор 80286 с 24-разрядной шиной адреса, инженеры Intel допустили ошибку, в результате которой даже в режиме совместимости с 8086/8088 этот бит не обнулялся, и там действительно максимальный физический адрес в DOS составлял 10FFEFh.

    Насчёт 0 и FFFF JAPH уже объяснял, но на всякий случай повторю несколько по-иному. 0 -- это все биты, равные нулю, FFFF -- это все 16 битов, равные 1. При программировании под DOS используются 16-разрядные регистры, поэтому-то максимальным значением и является FFFF. Если бы программа писалась под Windows (32 разряда), то максимальное значение было бы уже FFFFFFFF (32 единичных бита).

    Термин "параграф" появился из-за того, что адрес вычисляется путём сложения смещения и умноженного на 16 (10h) сегмента. Поскольку значение сегмента умножается на 16, путём изменения значения сегмента можно "скакать" по памяти, "перепрыгивая" сразу через 16 байт. Эти самые 16 байт и называются параграфом. Таким образом, если сегмент равен нулю, мы имеем дело с нулевым параграфом памяти (он расположен в физических адресах от 00000 до 0000F), если сегмент равен единице, мы имеем дело с первым параграфом (адреса 00010-0001F) и так далее.

    "Граница параграфа" -- это любой адрес, кратный размеру параграфа, то 16 байтам (или 10h, если в шестнадцатеричной системе). Шестнадцатеричный адрес на границе параграфа имеет в младшем разряде 0. Например, адреса 12340h, 23450h и 4EFB0h находятся на границе параграфа, а вот 12345h или 89ABCh -- нет.

    Ну а насчёт отнимания числа 1... Сколько чисел находится в диапазоне от 0 до 9 включительно? Не девять, как иногда сходу говорят, а 10 (0 -- тоже число). Поскольку в программировании отсчёт всего и вся реально начинается с нуля, постоянно приходится вычитать единицу, чтобы получить максимальное значение. Например, 64 килобайта -- это 65536 байт, но адреса их нумеруются от 0 до 65535 (т.е. на 1 меньше, чем общее количество байтов -- как раз потому, что их счёт начинается с нуля).
     
  5. sid

    sid New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2007
    Сообщения:
    6
    Я не могу это представить в голове! Можно рисунок этой памяти, чтобы было видно, где там сегмент, где граница параграфа и почему надо умножать на 16h а не прибавлять ? Только не ругайтесь.
     
  6. sid

    sid New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2007
    Сообщения:
    6
    Есил я вызываю DUMP памяти в debug.exe он мне показывает сегмент и смещение?
    1АА0:0100 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00

    1AA0 - сегмент, 0100 - смещение. нули это параграф. Или как?
     
  7. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    sid
    Совершенно верно

    Нули -- это данные. В данном случае этих данных ровно один параграф -- 16 байтов, начинающихся на границе параграфа (младшие 4 разряда адреса равны нулю).

    Можно представить себе всю память в виде последовательности байтов, пронумерованных от 00000 до FFFFF включительно (ровно 1 мегабайт, поскольку мы говорим про ДОС; все адреса шестнадцатеричные). Тогда параграфы будут начинаться через каждые 16 байтов: сначала байт с адресом 00000, потом -- 00010, потом -- 00020 и т.д.

    Сегмент фактически является номером параграфа, а смещение позволяет обращаться к данным внутри этого и следующим за ним параграфов.
     
  8. sid

    sid New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2007
    Сообщения:
    6
    Давайте сделаем по другому. Вот, как я понял:
    Память делится на сегменты. В одном сегменте 65535 байт(FFFF). Смещением я могу передвигаться по сегменту в пределах 65535 байт(FFFF). Получается, если я хочу обратиться к какому либо байту, я должен указать сегмент и смещение. т.е. FFFF:FFFF - последний сегмент последнее смещение. Я не понял зачем (почему) я должен умножить сегмент на 10h ?
    Вы пишите, что Вы со мной согласны, что сегмент = 65535(FFFF), а строчкой ниже Вы пишите, что сегмент = 1048560(FFFFF) ?????
    Вы поняли мой вопрос?
     
  9. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.347
    sid
    адрес сегмента в модели сегмент:смещение - это номер параграфа (16-ти байтового блока). Чтобы узнать реальный адрес первого байта сегмента, нужно умножить адрес сегмента на 16. И к нему уже потом прибавлять смещение.

    --

    тебе не нужно самому умножать адрес сегмента на 16. Это сделает процессор.
     
  10. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    sid
    В одном сегменте 65536 байт, смещения которых меняются от 0 (минимум) до FFFF (максимум).

    На самом деле сегменты в памяти перекрываются, потому что адрес сегмента кратен размеру параграфа (16 байтам). Например, физический адрес для логического FFFF:FFFF равен 0FFEF -- т.е., хотя сегмент FFFF и является последним, но попадаем мы с его помощью не только в самый конец памяти (максимальный физический адрес которой равен FFFFF), но и в начало, захватывая первые 64 килобайта без 16 байт.

    Умножает процессор. А Вам необходимо про это знать, чтобы понимать, как работает сегментация. Например, адреса 0000:0010 и 0001:0000 являются разными логическими адресами, но обращаются к одной физической ячейке памяти (имеющей адрес 00010).

    FFFFF -- это максимальный физический адрес памяти. Общий её объём составляет 1048576 байтов, или 1 мегабайт (физические адреса изменяются от 00000 до FFFFF).
     
  11. sid

    sid New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2007
    Сообщения:
    6
    Спасибо большое, теперь все понятно! Остался последний глупый вопрос: память 1 мег. , это оперативн. память? Что ДОС больше 1 мега не видит?
     
  12. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    sid

    ДОС -- нет, не видит, в реальном режиме доступен только 1 мегабайт. Вся память выше видится только в защищённом режиме.

    Кстати, собсно оперативной памяти там 640 килобайт (адреса от 0 до 9FFFF включительно). Дальше идёт видеопамять (A0000-BFFFF), а затем область ПЗУ, в т.ч. BIOS.

    Правда, если быть абсолютно точным, из-за ошибки, допущенной при разработке 80286, и в реальном режиме можно увидеть чуть-чуть памяти свыше 1 мегабайта -- а именно 64 килобайта минус 16 байт. Эта возможность включается-отключается разрешением-запрещением линии А20 (думаю, рано или поздно натолкнётесь на упоминание об этой фиче).

    Но лично моё мнение: нет смысла использовать эту лишнюю память (в ДОС, кстати, она называется HMA -- High Memory Area). Сейчас, в отличие от времён ДОСа, реальный режим используется только для учёбы, и эти 64 килобайта роли не сыграют. Ну а когда в реальном освоитесь, перейдёте в защищённый -- а там доступна вся память. Правда, там своих заморочек хватает, но это уже совсем другая история :)
     
  13. sid

    sid New Member

    Публикаций:
    0
    Регистрация:
    2 дек 2007
    Сообщения:
    6
    Все понял спасибо.