Программирование драйверов Windows

         

Доступ к регистрам устройств


Когда функционирование устройства стало почти понятным, останется небольшая проблема: как программно получить доступ к регистрам устройства.

Как правило, регистры следуют друг за другом в своем адресном пространстве. Следовательно, для начала, необходим адрес первого из них. К сожалению, значение термина 'адрес' сильно варьируется при использовании его относительно виртуальных адресных пространств на различных платформах.

  • Вариант первый. Используем специфическую для данного процессора инструкцию ввода/вывода в порт, а значит, нужен адрес порта ввода/вывода.
  • Вариант второй. Особые области в памяти совмещены с адресами доступа к устройству. Запись по адресу в памяти означает перенос данных в устройство. Самый распространенный прием для доступа к видеопамяти &#8212 доступ по специальным адресам с использованием стандартных обращений к памяти.
  • Пример старой DOS программы (назовем ee Abc), выполняющей вывод алфавита на экран в текстовом режиме, построен как раз на том, что видимая область первой текстовой страницы DOS экрана "совмещалась" с оперативной памятью и начиналась с адреса B800:0000 (что в переводе на современный... где-то... 0xB8000).

    #include &#60dos.h&#62 int main(void) { int i; unsigned int far *screen; // &#60- адрес начала видимой 1-й страницы // Собираем адрес из сегмента (0xB800) и смещения: screen = (unsigned int *) MK_FP(0xB800, 0); for (i = 0; i &#60 26; i++) screen[i] = 0x0F00 + ('a' + i); // &#60- Вывод одного символа return 0; }

    В результате работы этого кода (его следует собрать DOS компилятором) в верхней строке экрана появится строка букв о 'а' до 'z'. (Здесь 0x0F &#8212 байт означающий, что символы будут белыми на черном фоне.)

    Если говорить в терминах ассемблера, то инструкции для доступа к пространству памяти &#8212 это MOV (load/store

    для других типов ассемблера), а для доступа к пространству ввода/вывода используются инструкции типа IN или OUT.



    Содержание раздела