4.9.5. Интерфейс XMS

Спецификация доступа к дополнительной памяти (XMS) - еще один метод, позволяющий программам, запускающимся под управлением DOS в реальном ре­жиме (или в режиме V86), использовать память, расположенную выше границы

первого мегабайта.

INT

Вход:    АХ = 4300h: проверить наличие XMS

Выход: АН = 80h, если HIMEM.SYS или совместимый драйвер загружен Вход:   АХ = 431 Oh: получить точку входа XMS Выход: ES:BX = дальний адрес точки входа XMS

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

команды CALL на указанный дальний адрес.

Функция XMS 00k. Определить номер версии Вход:    АН = 00h

Выход: АХ = номер версии, не упакованный BCD (ОЗООЬдля 3.0) ВХ = внутренний номер модификации DX =    если        существует; 0, если нет

Функция XMS 08k Определить объем памяти Вход:    АН = 08h BL = OOh

Выход: АХ = размер максимального доступного блока в килобайтах

DX = размер XMS-памяти всего в килобайтах

BL = код ошибки (OAOh, если вся XMS-память занята; 00, если нет

ошибок)

Так как возвращаемый размер памяти оказывается ограниченным размером слова (65 535 Кб), начиная с версии XMS 3.0, введена более точная функция 88h.

Функция XMS88h: Определить объем памяти Вход:    АH = 88h

Выход: ЕАХ = размер максимального доступного блока в килобайтах :

BL - код ошибки (OAOh, если вся XMS-память занята; 00, если нет

ошибок)

ЕСХ = физический адрес последнего байта памяти (верный для ошиб­ки OAOh)

EDX = размер XMS-памяти в килобайтах (0 для ошибки OAOh)

Функция XMS 09k Выделить память Вход:   AH = 09h

DX = размер запрашиваемого блока (в килобайтах) Выход: АХ = І, если функция выполнена DX = идентификатор блока

АХ = 0:

BL = код ошибки (OAOh, если не хватило памяти) Функция Освободить память

Вход:   АH = OAh

DX = идентификатор блока Выход: АХ = І, если функция выполнена.

Иначе - АХ = 0 и BL = код ошибки (OA2h - неправильный идентифи­катор, OABh - участок заблокирован)

Функция XMSOBh: Пересылка данных

Вход: АН = OBh

DS:SI = адрес структуры для пересылки памяти Выход: АХ = 1, если функция выполнена

Иначе - АХ = 0 и BL = код ошибки

Структура данных, адрес которой передается в DS:SI:

+00h: 4 байта - число байтов для пересылки +04h: слово - идентификатор источника (0 для обычной памяти) +06h: 4 байта - смещение в блоке-источнике или адрес в памяти +OAh: слово - идентификатор приемника (0 для обычной памяти) +OCh: 4 байта - смещение в блоке-приемнике или адрес в памяти

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

Функция XMSOFh: Изменить размер XMS-блока

Вход:  АН - OFh

ВХ = новый размер

DX = идентификатор блока Выход: АХ = 1, если функция выполнена.

Иначе - АХ = 0 и BL = код ошибки

Кроме того, XMS позволяет программам использовать область НМА и блоки UMB, если они не заняты DOS при запуске (так как в CONFIG.SYS не было строк

DOS = HIGH или DOS = UMB).

; Сообщает размер памяти, доступной через EMS и XMS.

tiny

. code .186

org 100h

; Для команд сдвига на 4. ; СОМ-программа.

start:

eld ;   Команды строковой обработки будут выполняться вперед.

Проверка наличия EMS.

шоу mov

dx,offset ems_d river ax,3D00h

21h

Адрес

int jc

mov mov

no emmx

bx, ax ax,4400h

21h

Открыть файл или устройство. Если не удалось открыть - El Идентификатор в ВХ.

EMS нет.

int

jc

no_ems

проверить состояние файла/устройства. Если не произошла ошибка,

test dx,-80h jz no_ems

Определение версии EMS.

проверить старший бит DX.

Если он - О,   ЕММХХХХО - файл

в текущей директории.

mov int

test

jnz

mov and shr

call

ah,46h

67h

ah, ah

no_ems

ah, al al.OFh ah, 4

output_version ;; ГЯдаучить версию EMS.

;; ЕЕдпи EMS выдал ошибку I с ним работать.

не стоит продолжать

AALL = старшая цифра.

ffffl = младшая цифра. Выдать строку о номере версии EMS.

; Определение доступной EMS-памяти.

mov

ah,42b

 

int

67h

; Получить размер памяти

shl

dx,4

; РЖ = размер памяти в

shl

bx,4

; ВХ = размер свободной

mov

ax,bx

 

mov

si,offset ems.

^геетегл       ; Адрес строки

call

output_info

; Выдать строки

в 16-килобайтных страницах. килобайтах. памяти в килобайтах,

для

о размерах памяти.

no ems:

mov int ah,3Eh 21h

Закрыть   файл/устройство ЕММХХХХО.

no emmx:

наличия XMS.

mov

ax,4300h

 

 

int

2Fri

 

; Проверка ХМЭ.

cmp

al,80h

 

;   Если АЬ не равен 80п,

jne

no_xms

 

; ХМЭ отсутствует.

mov

ax,4310h

 

; Иначе:

int

2Fh

 

;  получить точку входа ХМ8

mov

word ptr

entry_pt,bx

; и сохранить ее в епРгу_рР.

mov

word ptr

entry_pt+2,es

;   (старшее слово - по старше

push

ds

 

 

pop

es

 

;  Восстановить ЕЭ.

Определение версии XMS. mov 00 call      dword ptr entry_pt mov        byte ptr mem_version,'X'

call

output_version

Определение доступной XMS-памяти.

mov ah,08h

xor bx,bx

call dword ptr entry_pt

Функция XMS OOh - номер версии.

Изменить первую букву строки

"EMS версии" на "X".

Выдать строку о номере версии XMS.

Функция XMS

mov     byte ptr

mov xms_freemem

Изменить первую букву строки "EMS-памяти" на "X". Строка для output_info.

Вывод сообщений на экран: РХ - объем всей памяти, АХ - объем свободной памяти, 81 - адрес строки с сообщением

о свободной памяти (разный для EMS и

output_info:

push

mov mov

call

pop mov

output_info1:

mov ax

ах, dx

bp,offset totalmem

output_info1

ax

bp,si

di,offset hex2dec_word

hex2dec

Преобразует целое двоичное число в АХ. В строку десятичных ASCII-цифр в ES:DI,

divlp:

store:

mov xor xor div

add push

inc

test

jnz

pop

stosb loop

mov

mov mov

int

mov

int

mov

int

no_xms: ret

bx,10 cx, cx dx, dx

bx

dl.'O'

dx

cx

ax, ax

divlp

ax

store

byte ptr es:[di], '$'

dx, bp ah,9 21n

dx,offset hex2dec_word

21h

dx,offset eol 21 h

Объем всей памяти в АХ. Адрес строки - в ВР. Вывод.

Объем Свободной памяти - в АХ. Адрес строки - в ВР.

Вывод.

заканчивающуюся символом ; Делитель в ВХ.

; Счетчик цифр в 0.

Разделить преобразуемое число на 10, добавить к остатку А8С11-код нуля записать полученную цифру в стек. Увеличить счетчик цифр и, если еще есть, что делить, продолжить деление на 10.

Считать цифру из стека. Дописать ее в конец строки в Е8:01. Продолжить для всех СХ-цифр. Дописать '$'  в конец строки.

; DX

адрес первой части строки.

вывод строки. с десятичным числом.

Функция DOS 09h DX - адрес строки Вывод строки.

DX - адрес последней части строки. Вывод строки.

; Конец программы ; и output_info1.

и процедур

Вывод версии

АХ - номер в неупакованном BCD-формате.

output_version:

or

■ Преобразование неупакованного BCD в ASCII.

mov

byte

ptr major, ah                        ;  Старшая цифра в major.

mov

byte

ptr minor,al                       ; Младшая цифра в minor.

mov

dx, offset mem_version                  ;  Адрес начала строки - в 0Х

mov

ah, 9

 

int

21h

■   Вывод строки.

ret

 

 

ems_driver

db

■ Имя драйвера для проверки EMS.

mem^version

db

"EMS   версии         ■   Сообщение о номере версии.

major

db

■  "О.--                 ;   Первые байты этой '

minor

db

"0 обнаружен ",OOh,OAh, ' $' ; и этой строк будут

 

 

■  заменены реальными номерами версий.

totalmem

db

"EMS-памяти: $"

ems_f reernem

db

"EMS-памяти: $"

eol

db

'K',ODh,OAh,'$'               ;  Конец строки.

xms_freemem

db

"Наиболвший свободный блок XMS: $"

entry_pt:

 

■   Сюда записывается точка входа XMS.

hex2dec_word

equ

entry_pt+4        ■ Буфер для десятичной строки.

end

start