Файл: О.А.Калашников. Ассемблер Это Просто. Учимся программировать.pdf

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

Категория: Книга

Дисциплина: Программирование

Добавлен: 16.02.2019

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

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

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

Глава 30. Работа с расширенной памятью 

289 

30.2. Программа XMSmem.asm.  
Получение объема XMS-памяти 

30.2.1. Подготовка к использованию расширенной 
памяти и вывод объема XMS-памяти 

Первое, что мы сделаем, — определим объем доступной XMS-памяти и выведем 

количество килобайт на экран при помощи известной нам уже процедуры с исполь-
зованием сопроцессора (ее мы уже рассматривали в предыдущих главах). 

Как  уже  отмечалось  ранее,  чтобы  использовать  расширенную  память,  необхо-

димо,  чтобы  в  памяти  был  загружен  специальный  драйвер,  который  бы  открыл 
доступ  к  ней.  В  DOS/Windows  такой  файл  называется  himem.sys.  Если  загрузить 
"чистую"  DOS  без  этого  драйвера, то программы смогут обращаться только к ос-
новной памяти (640 Кбайт). Следовательно, все файлы-приложения будут работать 
только в том случае, если загружен указанный выше файл (или его аналог). 

Первое, что нужно сделать, — проверить наличие драйвера himem.sys в памяти. 

Это позволяет сделать функция 

4300h

 прерывания 

2Fh

 (табл. 30.1). 

Таблица 30.1. Функция 

4300h

 

прерывания 

2Fh

: проверка на присутствие  

в памяти драйвера himem.sys 

Вход 

Выход 

ax = 4300h  

al = 80h 

— драйвер загружен 

 

Рис. 30.1. Проверка драйвера himem.sys 

Как провести проверку, показано в листинге 30.1 (во избежание недоразумений 

проверка будет осуществляться во всех трех файлах-приложениях). 


background image

 

Часть III. Файловая оболочка, вирус, резидент 

290 

Листинг 30.1. Проверяем наличие файла himem.sys 

... 
;Проверим на наличие himem.sys в памяти... 
mov ax,4300h 
int 2Fh 
 
cmp al,80h 
je Himem_loaded 

;Если al = 80h, то himem.sys загружен. 

 
;Иначе выводим сообщение о том, что himem в памяти не обнаружен... 
... 
 

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

памяти. Для этого вызываем собственную процедуру 

Prepare_XMS

, которая подго-

товится к работе с расширенной памятью, а также отведет блок памяти. 

Все  процедуры  по  управлению  XMS-памятью  вызываются  не  с  помощью  пре-

рываний  (как  функции  DOS — 

int  21h

),  а  с  использованием  команды  "дальний 

call

"  и  указанием  после  нее  сегмента  и  смещения  самой  процедуры.  Получить 

точку  входа  (адрес)  процедур  по  управлению  XMS-памятью  позволяет  функция 

4310h

 прерывания 

2Fh

 (табл. 30.2). 

Подобный принцип вызова процедур очень похож на вызов WinAPI. 

Таблица 30.2. Функция 

4310h

 

прерывания 

2Fh

: получить точку  

входа процедур управления XMS-памятью 

Вход 

Выход 

ax = 4310h 

es 

= сегмент, bx = смещение 

 
Рассмотрим это на примере. 
После того как получили точку входа, все остальные обращения к процедурам 

работы  с  XMS-памятью  будут  осуществляться  следующим  образом  (естественно, 
нужно предварительно загрузить необходимые данные в регистры или подготовить 
массивы данных): 

call dword ptr XMS_Addr 

В листинге 30.2 показано, как получить адрес обработчика XMS-функций и ко-

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

Листинг 30.2. Получаем адрес обработчика и объем свободной XMS-памяти 

... 
mov ax,4310h 
int 2Fh 
mov word ptr XMS_Addr,bx 
mov word ptr XMS_Addr+2,es        ;Сохраним обработчик XMS-функций 


background image

Глава 30. Работа с расширенной памятью 

291 

mov ah,88h                        ;Получить количество килобайт XMS-памяти 
call dword ptr XMS_Addr 
mov dword ptr Number_dec,edx      ;Сохраним полученное число 
... 

 

Рис. 30.2. Получить объем XMS-памяти 

Как  видно  из  примера,  функция  возвращает  количество  килобайт  (не  байт!)  

в 32-разрядный регистр 

edx

Обращаем  ваше  внимание,  что  данная  функция  может  работать  некорректно  

в  Windows  NT/2000/XP.  В  этом  случае  просто  загрузите  "чистую"  MS-DOS 5.00  
и выше и проверьте работоспособность этой функции. Более того, количество ки-
лобайт свободной XMS-памяти возвращает непосредственно операционная система, 
которая берет информацию не из CMOS, а ведет учет самостоятельно. Это значит, 
что информация, которую вернет функция, может не соответствовать действитель-
ности. DOS может указать не только реальный объем XMS-памяти, но и добавить  
к нему размер SWAP-файла Windows либо наоборот показать меньший размер, чем 
есть на самом деле, вычтя из реального объема размер памяти, отведенной под кэш. 
Все зависит от версии DOS/Windows. 

Теперь осталось только вывести полученный результат, используя написанную 

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

Out_dec

30.3. 

Программа XMSblock.asm. Чтение файла  

в расширенную память и вывод его на экран 

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

будем.  Для  данного  файла эти операции проводятся аналогично вышеописанным. 
Единственное исключение в том, что мы еще и отводим блок расширенной памяти 


background image

 

Часть III. Файловая оболочка, вирус, резидент 

292 

при  помощи  функции 

09h

  процедуры  управления  XMS-памятью  (рис. 30.3).  При 

этом регистр 

dx

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

(листинг 30.3). 

Листинг 30.3. Отведение блока XMS-памяти 

... 
mov ah,9 
mov dx,1024                ;Отводим 1024 Кбайт XMS-памяти 
call dword ptr XMS_Addr 
or ax,ax                   ;Ошибка? 
jnz XMS_OK 
... 
 
XMS_OK: 
mov XMS_id,dx              ;Сохраним id отведенного блока 
... 

В  случае  если  произошла  ошибка  (запрашиваемый  блок  больше  имеющегося  

в распоряжении и т. п.), то значение 

ax

 будет равно не нулю, а коду ошибки. 

 

Рис. 30.3. Отводим блок расширенной памяти 

Если ошибки не произошло, то 

dx

 будет содержать идентификационный номер 

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

3Dh

 прерывания 

21h

 возвраща-

ет номер открытого файла.  


background image

Глава 30. Работа с расширенной памятью 

293 

30.3.1. Работа с расширенной памятью 

Как  уже  ранее  отмечалось,  загружать  данные  напрямую  в  XMS-память  в  DOS 

невозможно. Для этого используется основная память (640 Кбайт). Сперва данные 
загружаются  в  отведенный  массив  в  основной  памяти,  затем  при  помощи  специ-
альной процедуры пересылаются в расширенную. Пересылка осуществляется бло-
ками, но не более чем по 64 Кбайт. 

В программе XMSblock.asm мы вначале читаем файл C:\autoexec.bat в отведен-

ный массив основной памяти и выводим его на экран. Затем перебрасываем прочи-
танные  байты  в  расширенную  память  и  обратно  в  основную,  но  уже  по  другому 
адресу. И снова выводим то, что перебрасывали. Идентичность выводимой инфор-
мации  подтверждает  то,  что  программа  не  имеет  ошибок:  данные  пересылаются  
в XMS-память и обратно. 

30.3.2. Структура массива при работе  
с XMS-памятью 

Для  работы  с  XMS-памятью  (пересылка  данных)  заведем  специальный  массив 

(листинг 30.4). Для удобства зададим каждой переменной название. В дальнейшем 
адрес данного массива будет загружаться в регистры 

ds:si

  перед вызовом специ-

альных подфункций функции управления XMS-памятью. 

Листинг 30.4. Переменные для работы с расширенной памятью 

... 
;Количество байтов для пересылки 
XMS_str dd 0 
 
;Источник 
XMS_src dw 0 
 
;Смещение в блоке-источнике или адрес в основной памяти 
XMS_offsrc dd 0 
 
;Идентификатор приемника 
XMS_rec dw 0 
 
;Смещение в блоке-приемнике или адрес в основной памяти 
XMS_offrec dd 0 
... 

Рассмотрим отдельно каждую переменную.  

  XMS_str

  (два  слова) —  должна  содержать  количество  байтов  для  пересылки  из 

основной памяти в XMS либо наоборот.