Приложения.

Адреса памяти и портов:

Теперь, когда Вы разобрались с шестнадцатиричными числами, можно разбираться в системе, которой пользуется процессор при адресации памяти. Во-первых, важно отметить, что имеется два типа адресов: адреса памяти и адреса портов. Hомера адресов используемые теми и другими совершенно не связаны; засылка значения в ячейку памяти с алресом 2000 не имеет ничего общего с засылкой значения в порт с адресом 2000. Доступ к портам осуществляется с помощью инструкций INP и OUT в Бейсике и IN в OUT языке ассемблера. Доступ к адресам памяти осуществляется в Бейсике инструкциями PEEK и POKE, а в языке ассемблера инструкцией MOV. Имеется 65K доступных адресов портов и 1024K доступных адресов памяти.

Поскольку процессор использует 16-битные регистры, то он намного быстрее вычисляет адреса памяти если они не превосходят по длине 16 битов. Однако максимальное число, которое может содержаться в 16 битах равно 65535. Мы будем представлять его как четырехзначное шестнадцатиричное число FFFFH. Требуется еще 4 добавочных бита, чтобы представить такое большое число как миллион (FFFFH), которому равен размер адресного пространства IBM PC (AT может иметь доступ к еще большей памяти, используя виртуальную адресацию, не рассматриваемую здесь).

Процессор решает проблему адресации более чем 64K с помощью 16-битного указателя за счет разбиения памяти на сегменты. Сегментом является любая непрерывная область памяти размером 64K; при этом 16-битный указатель может указывать на любой байт внутри него. Процессор хранит положение начала сегмента в мегабайтном адресном простанстве и рассматривает 16-битные адреса, как смещения относительно этой точки. Hо как определить эту точку? Ответ состоит в том, что второе двухбайтное значение используется для отметки начала сегмента и это значение умножается на 16 ( = 4 битам) перед его использованием. Таким образом, если это сегментное значение равно 2, то, умножив его на 16, получим 32, и адреса будут затем вычисляться как смещение относительно 32-го байта в памяти. Если адрес в сегменте равен 7, то суммируя 32 и 7 получаем, что нам нужно обратиться к 39-му байту памяти, а не к 7-му. Относительный адрес (или смещение) этого байта равен 7, а абсолютный адрес - 39.

В Бейсике Вы можете установить сегментный адрес с помощью оператора DEF SEG. Если Вы напишете оператор DEF SEG = 2, то установите начало сегмента, к которому Вы будете обращаться на 32-й байт, как в предыдущем примере. Затем Вы можете использовать операторы PEEK и POKE для чтения и записи отдельных байтов памяти. Hапример, PEEK(7) прочитает седьмой байт с начала сегмента, т.е. 39-й байт памяти.

Во многих местах этой книги мы ссылаемся на абсолютные адреса памяти. Это необходимо, поскольку операционная система хранит важную информацию в определенных местах. Абсолютные алреса приводятся в виде 0000:0000, где первые 4 шестнадцатиричные цифры указывают адрес сегмента, а вторые - относительный адрес (смещение). Вспоминая предыдущий пример, мы можем адресовать 39-й байт памяти записав 0002:0007. Отметим, что тот же самый адрес может быть записан в другом виде, если изменить значение сегментного регистра, например, 0001:0017. Этот адрес можно представить также в виде одного 5-значного шестнадцатиричного числа. Hапример, видеобуфер начинается с адреса B000:0000, который можно записать как B0000H. Отметим, что суффикс H опускается в специальной адресной нотации.

И последнее замечание относительно использования памяти. Kогда число занимает два или более байтов, то младший байт этого числа хранится в ячейке с меньшим адресом. Если целое число A48BH хранится, начиная с ячейки 1000:0007, то ячейка 0007 содержит 8B, а 0008 - A4. Подобным образом, если вещественное число хранится в памяти как F58CA98DH, то 8D будет храниться в ячейке с самым младшим адресом, а F5 - с самым старшим.


<~-7.3.4 Получение цифрового ввода из игрового порта.
Содержание
Приложение В. Основные сведения об языке ассемблера.-~>

Сайт управляется системой uCoz