Файл: jourdain_spravochnik_programmista.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 04.07.2020

Просмотров: 3051

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

два из них). Базовый адрес - это младший из адресов портов, отно-

сящихся к группе портов, имеющих доступ к данному каналу коммуни-

кации. Эти четыре поля начинаются с адреса 0040:0008. Порту COM1

соответствует адрес :0008, а COM2 - 000A. Если это поле содержит

0, то соответствующий порт отсутствует. Таким образом, если слово

по адресу :0008 отлично от нуля, а по адресу 000A - нулевое, то

имеется один порт коммуникации.

AT хранит информацию о периферии в регистре 14H микросхемы

конфигурации. Сначала запишите 14H в порт с адресом 70H, а затем

прочитайте содержимое регистра через порт 71H. Вот значение битов

этого регистра:


биты 7-6 00 = 1 НГМД, 01 = 2 НГМД

5-4 01 = вывод на цветной дисплей, 40 строк

10 = вывод на цветной дисплей, 80 строк

11 = вывод на монохромный дисплей

3-2 не используется

1 1 = имеется мат. сопроцессор

0 0 = нет НГМД, 1 = имеется НГМД


Высокий уровень.


В Бейсике нужно просто прочитать байты статуса из области

данных BIOS. В приложении Б объяснено выполнение битовых операций

в Бейсике. В приведенном примере проверка наличия дисковых нако-

пителей достигается проверкой четности младшего байта статусного

регистра (четный - нет накопителей).



100 DEF SEG = 0 'указывыаем на дно памяти

110 X = PEEK(&H410) 'получаем младший байт регистра

120 IF X MOD 2 = 0 THEN 140 'он четный - нет накопителей

130 PRINT "Имеется диск" 'иначе имеется накопитель

140 GOTO 160 'идем ко второму сообщению

150 PRINT "Нет накопителей" 'второе сообщение

160 ... 'продолжаем...


Проверка наличия COM1:


100 DEF SEG = 40H 'указываем на область данных BIOS

110 PORT = PEEK(0) + 256*PEEK(1) 'получаем слово со смещением 0

120 IF PORT = 0 THEN... '... то нет адаптера COM1


Средний уровень.


Прерывание 11H BIOS возвращает байт статуса оборудования в AX.

На входе ничего подавать не надо. В примере определяется число

дисковых накопителей.


; ---получение числа дисковых накопителей:

INT 11H ;получаем байт статуса

TEST AL,0 ;имеются накопители?

JZ NO_DRIVES ;переход, если нет

AND AL,1100000B ;выделяем биты 5-6

MOV CL,5 ;подготовка к сдвигу регистра

SHR AL,CL ;сдвиг вправо на 5 битов

INC AL ;добавляем 1, т.к. отсчет идет с 1


Низкий уровень.


Ассемблерная программа работает так же, как и программа на

Бейсике. В примере читается информация о конфигурации для AT,

определяя установлен ли математический сопроцессор:


MOV AL,14H ;номер регистра

OUT 70H,AL ;посылаем запрос

IN AL,71H ;читаем регистр

TEST AL,10B ;проверяем бит 1

JZ NO_COPROCESSOR ;если не установлен, то сопроцессора нет




1.1.7 Ревизия количества памяти.




Вопрос: "Сколько имеется памяти?",- может иметь три смысла.

О каком количестве памяти сообщают переключатели, установленные

на системной плате? Сколько микросхем памяти реально установлено

в машине? И, наконец, сколько остается свободной памяти, которую

DOS может использовать для выполнения Ваших программ? Машина


может иметь 10 банков памяти по 64K, но переключатели могут ука-

зывать на наличие только 320K, оставляя половину памяти для ка-

ких-либо специальных целей. А как может Ваша программа узнать,

сколько из доступных 320K она может использовать, учитывая, что

другое программное обеспечение может быть загружено резидентным в

верхнюю или нижнюю часть памяти?

Ответ на каждый вопрос можно получить своим способом. Для PC и

XT установка переключателей может быть просто прочитана через

порт B микросхемы интерфейса с периферией 8255. В пункте [1.1.1]

описано как это делается. BIOS хранит двухбайтную переменную по

адресу 0040:0013, которая сообщает число килобайт используемой

памяти. Для PCjr бит 3 порта 62H (порт C микросхемы 8255) равен

нулю, когда машина имеет добавочные 64K памяти. AT дает особо

полную информацию о памяти. Регистры 15H (младший) и 16H (стар-

ший) микросхемы информации о конфигурации говорят сколько памяти

установлено на системной плате (возможны три значения: 0100H -

для 256K, 0200H - для 512K и 0280H для 512K плюс 128K на плате

расширения). Память канала ввода/вывода для AT сообщается регист-

рами 17H и 18H (с инкрементом 512K). Память сверх 1 мегабайта

доступна через регистры 30H и 31H (опять с инкрементом 512K,

вплоть до 15 мегабайт). Если AT имеет 128K на плате расширения,

то установлен бит 7 регистра 33. Во всех случаях надо сначала

послать номер регистра в порт 70H, а затем прочитать значение из

порта 71H.

Легко написать программу, которая прямо тестирует наличие

памяти через определенные интервалы адресного пространства. Пос-

кольку минимальная порция памяти 16 килобайт, то достаточно про-

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

убедиться, что все 16K присутствуют. Когда данная ячейка памяти

отсутствует, то при чтении из нее получаем значение 233. Для

проверки можно записать в ячейку произвольное число, отличное от

233 и сразу же считать его. Если вместо посланного числа возвра-

щается 233, то соответствующий банк памяти отсутствует. Не приме-

няйте этот способ на AT, где при попытке писать в несуществующую

память вступает в действие встроенная обработка несуществующей

памяти. Диагностика AT настолько хороша, что Вы можете целиком

положиться на системную информацию о конфигурации.

Память постоянно занимается частями операционной системы,

драйверами устройств, резидентными программами обработки прерыва-

ний и управляющими блоками MS DOS. При проверке банков памяти Вы

не должны вносить необратимых изменений в содержимое памяти.

Сначала надо сохранить значение, хранящееся в тестируемой ячейке,

затем проверить ее и восстановить первоначальное значение.

Имеется еще одна проблема. Если Ваша процедура хотя бы времен-

но модифицирует свой код, то это может привести к краху. Поэтому

для проверки надо выбирать такую ячейку из блока 64K, которая не


будет занята текстом Вашей процедуры. Для этого поместите проце-

дуру тестирования впереди программы, а для тестирования выберите



ячейку со смещением равным смещению для кодового сегмента. Напри-

мер, если регистр кодового сегмента содержит 13E2, то сегмент

начинается со смещения 13E2 во втором 64K-байтном блоке памяти.

Поскольку Ваша подпрограмма проверки не может находиться по этому

адресу, то Вы можете безопасно проверять значение 3E2 в каждом

блоке. Запрет прерываний [1.2.2] позволяет не беспокоиться о

модификации кода из-за аппаратных прерываний, которые могут

происходить во время проверки.

Определение количества памяти реально доступной операционной

системе также требует некоторого фокуса. Когда программа первый

раз получает управление, то DOS отводит ей всю доступную память,

включая верхнюю область памяти, содержащую нерезидентную часть

DOS (которая автоматически перезагружается, если она была модифи-

цирована). Для запуска другой программы из текущей или для того,

чтобы сделать программу подходящей для многопользовательсой сис-

темы, необходимо урезать программу до требуемого размера. В пунк-

те [1.3.1] описано как это сделать с помощью функции 4AH прерыва-

ния 21H.

Эта же функция может быть использована для расширения отведен-

ной памяти. Поскольку программе отводится вся доступная память

при загрузке, то такое расширение невозможно при старте. Если Вы

попробуете сделать это, то будет установлен флаг переноса, в

регистре AX появится код ошибки 8, а в регистре BX будет возвра-

щено максимальное число доступных 16-байтных параграфов. Эта

информация как раз и нужна. Значит надо выдать запрос со слишком

большим значением в регистре BX ( скажем, F000H параграфов), а

затем выполните прерывание. Позаботьтесь о том, чтобы выполнить

эту функцию в самом начале программы, пока регистр ES еще имеет

начальное значение.


Высокий уровень.


Интерпретатор Бейсика использует только 64K (хотя операторы

PEEK и POKE позволяют доступ к памяти за пределами 64K). Доля

памяти доступная в настоящий момент возвращается функцией FRE.

Эта функция имеет фиктивный аргумент, который может быть числовым

или символьной строкой. BYTES = FRE(x) передает в BYTES число

свободных байтов. BYTES = FRE(x$) делает то же самое. Но строко-

вый аргумент вынуждает очистку области данных перед тем как возв-

ратить число байтов. Заметим, что если размер рабочей области

устанавливается с помощью оператора CLEAR, то количество памяти,

сообщаемое функцией FRE будет на от 2.5 до 4 килобайт меньше

из-за потребностей рабочей области интерпретатора.

Транслятор Бейсика не накладывает ограничение 64K на суммарный

объем кода и данных. Но сам компилятор ограничен тем количеством

памяти, которое он может использовать при компиляции. Если этого

пространства недостаточно, то уничтожьте все ненужные номера


строк при помощи ключа компиляции /N. Можно также использовать

более короткие имена переменных.



Средний уровень.


Прерывание 12H BIOS проверяет установку переключателей и возв-

ращает в AX количество килобайт памяти в системе. Эта величина

вычисляется из установки регистров микросхемы 8255 или, для AT,

микросхемы конфигурации/часов. Входных регистров нет. Имейте

ввиду, что установка переключателей может быть неверной, что

ограничивает достоверность такого подхода.

Для определения числа 16-байтных параграфов, доступных для

DOS, используйте функцию 4AH прерывания 21H. ES должен иметь то

же значение, что при старте задачи:


;---определение числа параграфов доступных для DOS

MOV AH,4AH ;указываем нужную функцию

MOV BX,0FFFFH ;требуем слишком большую память

INT 21H ;BX содержит число доступных параграфов


AT использует функцию 88H прерывания 15H для проверки наличия

расширенной памяти, которая ищет память вне адресного пространст-

ва процессора в обычном режиме адресации. Говорят, что она ищет

память за отметкой 1 мегабайта. При этом на системной плате дол-

жно быть от 512 до 640 килобайт памяти, чтобы эта функция рабо-

тала. Число килобайтных блоков расширенной памяти возвращается в

AX.


Низкий уровень.


Первый пример проверяет число банков памяти по 64K в первых

десяти 64-килобайтных сегментах памяти. Если Вы будете проверять

старшие 6 банков памяти, то имейте ввиду, что имеются видеобуфер,

начиная с B000:0000 (и, возможно, A000:0000) и ПЗУ, начиная с

F000:0000 (и, возможно, C000:0000).


;---проверка каждого банка памяти:

CLI ;запрет аппаратных прерываний

MOV AX,CS ;получаем значение кодового сегмента

AND AX,0FFFH ;сбрасываем старшие 4 бита

MOV ES,AX ;помещаем указатель в ES

MOV DI,0 ;DI считает число банков памяти

MOV CX,10 ;будем проверять 10 банков

MOV BL,'X' ;для проверки используем 'X'

NEXT:

MOV DL,ES:[0] ;сохраняем значение тестируемой ячейки

MOV ES:[0],BL ;помещаем 'X' в эту ячейку

MOV DH,ES:[0] ;читаем тестируемую ячейку

MOV ES:[0],DL ;восстанавливаем значение

CMP DH,'X' ;совпадает с тем, что писали?

JNE GO_AHEAD ;если нет, то банк отсутствует

INC DI ;увеличиваем число банков

GO_AHEAD:

MOV AX,ES ;готовим увеличение указателя

ADD AX,1000H ;указываем на следующие 64K

MOV ES,AX ;возвращаем указатель в ES

LOOP NEXT ;обрабатываем следующий банк

STI ;разрешаем аппаратные прерывания




Раздел 2. Управление прерываниями.




Прерывания это готовые процедуры, которые компьютер вызывает

для выполнения определенной задачи. Существуют аппаратные и прог-

раммные прерывания. Аппаратные прерывания инициируются аппарату-

рой, либо с системной платы, либо с карты расширения. Они могут

быть вызваны сигналом микросхемы таймера, сигналом от принтера,

нажатием клавиши на клавиатуре и множеством других причин. Аппа-

ратные прерывания не координируются с работой программного обес-


печения. Когда вызывается прерывание, то процессор оставляет свою

работу, выполняет прерывание, а затем возвращается на прежнее

место. Для того чтобы иметь возможность вернуться точно в нужное

место программы, адрес этого места (CS:IP) запоминается на стеке,

вместе с регистром флагов. Затем в CS:IP загружается адрес прог-

раммы обработки прерывания и ей передается управление. Программы

обработки прерываний иногда называют драйверами прерываний. Они

всегда завершаются инструкцией IRET (возврат из прерывания),

которая завершает процесс, начатый прерыванием, возвращая старые

значения CS:IP и регистра флагов, тем самым давая программе воз-

можность продолжить выполнение из того же состояния.

С другой стороны, программные прерывания на самом деле ничего

не прерывают. На самом деле это обычные процедуры, которые вызы-

ваются Вашими программами для выполнения рутинной работы, такой

как прием нажатия клавиши на клавиатуре или вывод на экран. Одна-

ко эти подпрограммы содержатся не внутри Вашей программы, а в

операционной системе и механизм прерываний дает Вам возможность

обратиться к ним. Программные прерывания могут вызываться друг из

друга. Например, все прерывания обработки ввода с клавиатуры DOS

используют прерывания обработки ввода с клавиатуры BIOS для полу-

чения символа из буфера клавиатуры. Отметим, что аппаратное пре-

рываение может получить управление при выполнении программного

прерывания. При этом не возникает конфликтов, так как каждая

подпрограмма обработки прерывания сохраняет значения всех исполь-

зуемых ею регистров и затем восстанавливает их при выходе, тем

самым не оставляя следов того, что она занимала процессор.

Адреса программ прерываний называют векторами. Каждый вектор

имеет длину четыре байта. В первом слове хранится значение IP, а

во втором - CS. Младшие 1024 байт памяти содержат вектора преры-

ваний, таким образом имеется место для 256 векторов. Вместе взя-

тые они называются таблицей векторов. Вектор для прерывания 0

начинается с ячейки 0000:0000, прерывания 1 - с 0000:0004, 2 - с

0000:0008 и т.д. Если посмотреть на четыре байта, начиная с адре-

са 0000:0020, в которых содержится вектор прерывания 8H (прерыва-

ние времени суток), то Вы обнаружите там A5FE00F0. Имея ввиду,

что младший байт слова расположен сначала и что порядок IP:CS,

это 4-байтное значение переводится в F000:FEA5. Это стартовый

адрес программы ПЗУ, выполняющей прерывание 8H. На рис. 1-2 пока-

зана схема выполнения программой прерывания 21H.




1.2.1 Программирование контроллера прерываний 8259.




Для управления аппаратными прерываниями во всех типах IBM PC

используется микросхема программируемого контроллера прерываний

Intel 8259. Поскольку в ккаждый момент времени может поступить не

один запрос, микросхема имеет схему приоритетов. Имеется 8 уров-

ней приоритетов, кроме AT, у которого их 16, и обращения к соот-