Глава 1. Системные ресурсы.

Раздел 1. Ревизия системных ресурсов.

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 присутствуют. Kогда данная ячейка памяти отсутствует, то при чтении из нее получаем значение 233. Для проверки можно записать в ячейку произвольное число, отличное от 233 и сразу же считать его. Если вместо посланного числа возвращается 233, то соответствующий банк памяти отсутствует. Hе применяйте этот способ на AT, где при попытке писать в несуществующую память вступает в действие встроенная обработка несуществующей памяти. Диагностика AT настолько хороша, что Вы можете целиком положиться на системную информацию о конфигурации.

Память постоянно занимается частями операционной системы, драйверами устройств, резидентными программами обработки прерываний и управляющими блоками MS DOS. При проверке банков памяти Вы не должны вносить необратимых изменений в содержимое памяти. Сначала надо сохранить значение, хранящееся в тестируемой ячейке, затем проверить ее и восстановить первоначальное значение.

Имеется еще одна проблема. Если Ваша процедура хотя бы временно модифицирует свой код, то это может привести к краху. Поэтому для проверки надо выбирать такую ячейку из блока 64K, которая не будет занята текстом Вашей процедуры. Для этого поместите процедуру тестирования впереди программы, а для тестирования выберите ячейку со смещением равным смещению для кодового сегмента. Hапример, если регистр кодового сегмента содержит 13E2, то сегмент начинается со смещения 13E2 во втором 64K-байтном блоке памяти. Поскольку Ваша подпрограмма проверки не может находиться по этому адресу, то Вы можете безопасно проверять значение 3E2 в каждом блоке. Запрет прерываний {1.2.2} позволяет не беспокоиться о модификации кода из-за аппаратных прерываний, которые могут происходить во время проверки.

Определение количества памяти реально доступной операционной системе также требует некоторого фокуса. Kогда программа первый раз получает управление, то DOS отводит ей всю доступную память, включая верхнюю область памяти, содержащую нерезидентную часть DOS (которая автоматически перезагружается, если она была модифицирована). Для запуска другой программы из текущей или для того, чтобы сделать программу подходящей для многопользовательсой системы, необходимо урезать программу до требуемого размера. В пункте {1.3.1} описано как это сделать с помощью функции 4AH прерывания 21H.

Эта же функция может быть использована для расширения отведенной памяти. Поскольку программе отводится вся доступная память при загрузке, то такое расширение невозможно при старте. Если Вы попробуете сделать это, то будет установлен флаг переноса, в регистре AX появится код ошибки 8, а в регистре BX будет возвращено максимальное число доступных 16-байтных параграфов. Эта информация как раз и нужна. Значит надо выдать запрос со слишком большим значением в регистре BX ( скажем, F000H параграфов), а затем выполните прерывание. Позаботьтесь о том, чтобы выполнить эту функцию в самом начале программы, пока регистр ES еще имеет начальное значение.

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

Прерывание 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.

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

Первый пример проверяет число банков памяти по 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 ;разрешаем аппаратные прерывания


<~-1.1.6 Определение числа и типа периферийных устройств.
Содержание
Раздел 2. Управление прерываниями.-~>

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