Системное программное обеспечение персональных ЭВМ


в программе пользователя команды INT



Схема 1



Рисунок 1.1. Уровни программного доступа к средствам ПЭВМ Перед выполнением в программе пользователя команды INT 21H программист должен занести в регистр AH некоторый код - номер той программы из состава DOS, которую требуется выпол- нить. Остальные регистры, как и при обращении к BIOS, используются для передачи параметров. Принято говорить о "функции DOS номер NN", имея в виду обращение к прерыванию 21 с кодом NN в регистре AH. Некоторые функции созданы разработчиками системы "для внутреннего использования": они вызываются из других функций и программ DOS, их описания отсутствуют в документации фирм IBM и Microsoft и, видимо, не предполагалось обращение к ним из программ пользователя.

Несмотря на это, в некоторых источниках можно найти описание ряда недокументированных функций DOS. Для некоторых задач обращение к недокументированной функции DOS является полезным, а возможно, и единственным путем решения, но следует всегда иметь в виду, что одинаковая работа одной и той же недокументированной функции в разных версиях DOS не гарантируется.

Существуют различия между наборами функций, доступными в разных версиях DOS. Как правило, новая версия наследует все возможности предшествовавшей и расширяется дополнительными возможностями. Наиболее значительным нам представляется скачок между версиями 2 и 3. И дело тут даже не столько в существенном расширении возможностей, а в изменении самого подхода разработчиков: начиная с версии 3.0 в создании системы стали использоваться методы, применявшиеся для больших вычислительных систем. Поэтому далее в нашем пособии там, где упоминаются "старые" и "новые" ("современные") версии DOS, имеются в виду версии до 3.0 и от 3.0 включительно.

Наконец, языки высокого уровня включают в себя процедуры и функции, обеспечивающие еще более высокий уровень интеграции. Как правило, эти процедуры/функции имеют содержательные имена и использующий их программист не обязан знать, через какой уровень эти процедуры/функции воздействуют на аппаратные средства. Средства языков должны быть предметом отдельного рассмотрения, которое в наши задачи не входит.

Идеальным, конечно, является использование на каждом уровне только средств ближайшего снизу уровня, но идеал редко осуществим полностью, поэтому, в частности, программа пользователя имеет доступ ко всем уровням. Хотя в соответствии с целями нашего пособия смешения обращений на разные уровни встречаются здесь почти повсеместно, в практической работе автор является убежденным приверженцем идеала и горячо рекомендует его своим читателям. При решении прикладных задач каждое обращение к более низкому уровню должно быть непременно оправдано либо функциональной необходимостью, либо существенным выигрышем в эффективности. Такой подход, во-первых, существенно упрощает программирование и дает лучшую защиту от программистских ошибок, а во-вторых, лучше обеспечивает независимость программного изделия от конфигурации аппаратных средств и от версии DOS.




Схема 1



Рисунок 3.1. Совместная обработка прерывания несколькими программами <



Схема 1



Рисунок 4. 1 Распределение адресного пространства ПЭВМ
(все адреса шестнадцатиричные).
Адреса c 0000:0000 по 0000:03FF (1 Кбайт) занимает таблица векторов прерываний. Отметим, что векторы могут содержать адреса программ-обработчиков, адреса таблиц данных или быть свободными. По спецификациям DOS вектора с номерами от 0x60 по 0x67 свободны и могут заниматься программами пользователей. Однако, если пользователю необходимо использовать собственное прерывание, ему нельзя выбрать любой вектор из указанного диапазона без проверки. В этот момент в памяти ПЭВМ могут находиться какие-то резидентные программы (например, драйверы-русификаторы), которые могут использовать эти же вектора. Свободные векторы (а они могут найтись и вне специфицированной области) найти легко: эти векторы содержат нулевые адреса или константу NULL Турбо-Си.



Программа, приведенная ниже, выводит на экран таблицу векторов прерываний и определяет свободные векторы. Впоследствии мы укажем путь создания более совершенного варианта такой программы.

/*= ПРИМЕР 4.1. =*/ /*============= Анализ таблицы векторов =============*/ #include <dos.h> #include <stdlib.h> void *readvect(int in); main() { void far *vect; /* вектор */ int intnum; /* номер прерывания */ int line, i; for (clrscr(),intnum=line=0; intnum<l;256; intnum++) { for (i=0;i<17;i+=16) { vect=readvect(intnum+i); printf("INT %02Xh - %Fp - ",intnum+i,vect); if (vect==NULL) printf("%-16s","Свободен"); else printf("%-16s","Занят"); } if (i) { printf("\n"); if (++line>15) { intnum+=16; line=0; getch(); clrscr(); } } } } /*==== Получение вектора ====*/ void *readvect(int in) { union REGS rr; struct SREGS sr; rr.h.ah=0x35; rr.h.al=in; intdosx(&rr,&rr,&sr); return(MK_FP(sr.es,rr.x.bx)); }

Адреса с 0040:0000 по 0040:00FF (256 байт) называются областью памяти BIOS. В некоторых описаниях - областью памяти ROM BIOS. Приставка ROM (Read Only Memory, т.е. ПЗУ) говорит не о том, что эта память защищена от чтения, а о том, что данные в этой области используются программами, находящимися в ПЗУ.



Схема 1


Рисунок 13. 1 Связи между системными блоками DOS

На основании предложенной схемы можно попытаться строить гипотезы о выполнении системой запросов пользовательских программ на операции, например, ввода-вывода. Так, для чтения информации из файла пользовательская программа передает системе в составе запроса дескриптор обрабатываемого файла. Система при получении запроса выбирает PID активной в данный момент программы, являющийся адресом ее PSP. PSP программы содержит ссылку на ее JFT, полученный системой файловый дескриптор является номером элемента JFT. Элемент, выбранный по дескриптору из JFT, является входом в системную таблицу файлов, по которому выбирается DFCB требуемого файла. По-видимому, для символьных устройств система сразу же формирует запрос к драйверу, адрес которого содержится в DFCB. Для блочных устройств система по ссылке в DFCB выбирает DPB для блочного устройства. Используя данные о физических парамет- рах диска и системные структуры данных (FAT и каталоги, не- которые из которых, возможно, уже находятся в дисковых буфе- рах, а недостающие - считываются в них), система формирует основной параметр для обращения к драйверу блочного устройс- тва - номер сектора. Однако, прежде чем выдать драйверу зап- рос на ввод требуемого сектора система просматривает список BCB - для каких-то случаев информация может уже быть прочи- тана в дисковый буфер. Читатель сам может распространить подход, пример которого мы привели, на другие виды операций ввода-вывода.

Представляет интерес также анализ распределения памяти DOS, который можно провести, зная структуру связей между системными блоками. Анализ распределения памяти, выполняемый программой примера 12.1, во всех случаях показывает, что первый, значительный по размеру блок распределяемой памяти всегда принадлежит DOS. Что же содержится в этом блоке? Предоставим читателю самому сделать такую компиляцию из примеров этой главы, которая позволит проанализовать, какие системные структуры располагаются в ядре DOS, а какие - в распределенной DOS памяти, здесь же мы приводим (Рисунок 13.2) результат одного из выполнений такой программы. Цифры названий областей обозначают:
*1- назначение описано в источниках, восходящих к фирмам IBM и Microsoft;
*2- назначение области определено экспериментально;
*3- назначение предположительно;
*4- назначение неизвестно.





Схема 1



Рисунок 15. 1 Манипуляции со стеком
при обращении к прежнему обработчику

<

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