В этой статье я познакомлю тебя с сегментной адресацией и сегментными регистрами, расскажу, как распределяется первый мегабайт оперативной памяти компьютера, затем мы обсудим получение прямого доступа к видеопамяти в текстовом режиме, а самое главное — поностальгируем по фильму «Хакер»! Под конец напишем психоделическую программу, которой позавидовали бы его герои.
 

Знакомимся с сегментными регистрами

Для начала разберемся, что такое сегментные регистры. Процессор 8088 умеет адресовать один мегабайт оперативной памяти, несмотря на то что регистры у него 16-битные. В норме 16 битами можно адресовать только 64 Кбайт. И как же тогда выкручивается 8088? Как ему удается адресовать целый мегабайт? Для этого в 8088 есть сегментные регистры! Четыре сегментных регистра: CS, ES, DS и SS, по 16 бит каждый. У каждого из этих регистров есть свое назначение.

Регистр CS указывает на сегмент кода. Процессор обращается к CS всякий раз, когда надо считать из памяти очередную инструкцию для выполнения.

Регистры DS и ES указывают на сегмент данных. К этим регистрам процессор обращается, когда выполняемая инструкция считывает или сохраняет данные. Имей в виду: DS используется чаще, чем ES. ES обычно вступает в игру, когда ты обрабатываешь массивы данных, индексируя их регистром DI.

Регистр SS указывает на сегмент стека. К этому регистру процессор обращается, когда выполняет инструкции, взаимодействующие со стеком: push, pop, call и ret.

Значения, хранимые в сегментных регистрах, — это базовый адрес, поделенный на 16. Если в CS записано значение 0x0000, процессор будет считывать инструкции из области памяти 0x00000 — 0x0FFFF. Если в регистре CS записано значение 0x1000, то процессор будет считывать инструкции из области памяти 0x10000 — 0x1FFFF.

Если тебе надо адресоваться в какой-то другой сегмент, а не тот, который будет задействован по умолчанию, напиши этот сегмент в префиксе к инструкции, которую используешь.

Поместить какое-то число в сегментные регистры напрямую нельзя. Для этого надо:

  • либо сначала записать число в какой-нибудь регистр и уже этот регистр присвоить сегментному регистру;
  • либо воспользоваться парой инструкций push/pop;
  • либо воспользоваться инструкциями lds/les.

Процессор 8088 настолько лоялен, что позволит тебе даже вот такую инструкцию: pop cs. Но только имей в виду, что это нарушит поток выполнения инструкций. В более новых процессорах, начиная с 80286, такую диверсию сделать уже не получится. И слава богу!

Ну вот вроде бы и все, что тебе надо знать о сегментных регистрах. Теперь ты с их помощью (в основном с помощью регистров DS и ES) можешь получать доступ ко всему первому мегабайту памяти ПК.

 

Как ПК распределяет память

Понимание того, как распределяется память в ПК, поможет тебе делать разные интересные вещи.

Начало загрузки у всех компьютеров одинаковое: они сначала переходят в текстовый цветной режим 80x25. К видеопамяти экрана, который работает в таком режиме, можно обращаться напрямую, через вот этот диапазон адресов: 0xB8000 — 0xB8FFF.

Первый байт диапазона — это первый символ в верхнем левом углу экрана. Второй байт — это цвет фона под символом и цвет самого символа. Затем (третьим байтом) идет второй символ. И так для всех 25 строк по 80 символов каждая.

INFO

Исторический факт. IBM PC образца 1981 года поставлялся в двух модификациях: с монохромным режимом и с цветным режимом. Тогдашним разработчикам игрушек приходилось придумывать разные эвристики, чтобы понять, какая у компьютера графика — монохромная или цветная. Несколько старых добрых игрушек для этого писали какую-нибудь цифру по адресу 0xB8000 и считывали ее обратно, чтобы узнать, в каком режиме сейчас идет работа — в цветном или в монохромном.

 

Прямой доступ к видеопамяти в текстовом режиме

Перед тем как мы сможем напрямую обращаться к видеопамяти экрана, то есть без использования сервисов BIOS, надо задать нужный нам видеорежим.

В этом режиме видеопамять экрана доступна по адресу 0xB8000. Теперь ты можешь легко получить доступ к ней. Примерно так, как в коде ниже.

Обрати внимание, что после того, как ты выполнил этот кусок кода, ты не сможешь обращаться к переменным, которые сохраняешь в сегменте кода, как мы это делали в примерах из прошлых уроков. Потому что DS и ES теперь нацелены не на сегмент кода, а на видеопамять.

Продолжение доступно только участникам

Материалы из последних выпусков становятся доступны по отдельности только через два месяца после публикации. Чтобы продолжить чтение, необходимо стать участником сообщества «Xakep.ru».

Присоединяйся к сообществу «Xakep.ru»!

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Антон Карев

Антон Карев

Окончил физтех Алтайского госуниверситета. 20 лет занимаюсь низкоуровневым программированием на Ассемблере и Си. С уклоном в Secure Coding. Провожу в скайпе индивидуальные уроки по программированию на Ассемблере, Си, Питоне. Хочешь пообщаться? Пиши на email: anton.barnaul.1984@mail.ru

Check Also

NFTables. Разбираем преимущества перехода с iptables на новый файрвол

NFTables — новая реализация файрвола в ядре Linux, которая призвана заменить iptables. Как…

7 комментариев

  1. Аватар

    Maxim Elchugin

    14.09.2020 в 22:32

    Разве в современных операционных системах это актуально?

  2. Антон Карев

    Антон Карев

    14.09.2020 в 23:54

    Да, актуально. Работа с памятью и сегментация будут актуальными всегда. Да, они сегодня других размеров и называются по-другому, но сам принцип остаётся. Вот этому принципу и посвящена статья. Разобравшись с самим принципом, можно полученные знания транслировать — и на современные ОС, и на те, которые после них появятся, с ещё более новыми архитектурными особенностями.

  3. Аватар

    Victor__v

    17.09.2020 в 10:17

    На мой взгляд, учить сейчас людей ассемблеру под 16 бит преступление против здравого смысла.
    Не актуально же!

    Так уж сложно под 32 или 64?

    • Антон Карев

      Антон Карев

      17.09.2020 в 17:05

      Здравый смысл вещь субъективная. А основы никто не отменял. Кроме того, BIOS, когда компьютер только включился, смотрит на любой процессор (даже если это Ryzen или Core i9) – как на примитивный 16-битный 8088.

      Я убеждён, что на первых парах лучше учить ассемблер – на той версии процессора, где наворотов по минимуму. А потом, когда основы хорошо усвоены, можно легко и в новых наворотах разобраться.

      Я учился именно так (и своим студентам рекомендую также), и мне поэтому сейчас сравнительно легко в новомодных наворотах разбираться. Смотри, например, мои статьи про SIMD (https://xakep.ru/2019/07/30/interprocess/) и SGX (https://xakep.ru/2019/04/04/sgx-attack/). Но если сразу, например, в SIMD или SGX погружаться, то именно эти технологии ты может быть и освоишь, хорошо, – но поскольку у тебя нет системного понимания как работает процессор в самой своей основе, то каждую следующую модную технологию нужно будет изучать как с нуля.

  4. Аватар

    robotobor

    22.09.2020 в 10:14

    Зачетный был фильмец! «мы проверяем шестой бит (0x40)» — вроде, как 7ой бит…

Оставить мнение