Иллюстрированный самоучитель по SVGA

Использование функций DOS

Вычисление SwpSeg и GenSeg

В примере Б.4 показан фрагмент начала текста программы, в котором производится сокращение размера блока задачи и выделение двух блоков для размещения буферов обмена и общего назначения. Для описания основных сегментов в примере использованы специальные директивы (см. пример Б.2).

Пример Б.4. Получение от DOS значений переменных SwpSeg и GenSeg.

dosseg задаем расположение сегментов
.model small выбор модели памяти
.stack 200h задаем стековый сегмент
.data начало сегмента данных
wpOffs dw 0 смещение в буфере обмена
wpSeg dw 0 сегмент буфера обмена
enOffs dw 0 смещение в буфере
enSeg dw 0 сегмент буфера общего назначения
;Далее располагаются другие данные, используемые в задаче
.code начало кодового сегмента
.386 набор команд процессора
tart: mov ax, @data ax = код сегмента данных
mov ds, ax ds = ax
mov ax, ss ax = код стекового сегмента
mov bx, es bx = код сегмента, содержащего PSP
sub ах, bx ах = ах – bx
mov bx, sp bx = размер стека в байтах
shr bx, 04 превращаем его в параграфы
add bx, ax bx = bx + ах, размер задачи
mov ax, 4AOOh код запроса на сокращение блока
int 2 In DOS сокращает блок задачи
mov bx, lOOOh bx = размер блока в параграфах
mov ax, 480Ch код запроса на выделение блока
int 21h обращение к DOS
mov SwpSeg, ax SwpSeg = код сегмента блока
mov bx, lOOOh bx = размер блока в параграфах
mov ax, 4800h код запроса на выделение блока
int 21h обращение к DOS
mov GenSeg, ax GenSeg = код сегмента блока
; Далее следует продолжение текста программы
END start конец текста программы

Первые две команды примера Б.4 записывают в регистр ds код сегмента шных, который в этом случае имеет имя Sdata. Следующие 6 команд формируют в регистре bx значение tasksize, затем происходит вызов функции OS 4дь для сокращения размера блока задачи. При выполнении этой функции неиспользуемая память возвращается DOS, и теперь ее можно запрашивать для размещения дополнительных блоков.

В примере Б.4 сначала запрашивается место для размещения буфера обмена, затем буфера общего назначения. В обоих случаях в регистре bx указывает на размер блока в параграфах (юооь), а в регистре ah – код функции 48h (locate memory) и происходит обращение к DOS. После возврата из DOS код выделенного сегмента сохраняется в переменных SwpSeg или GenSeg. В отличие от примера Б.3 размер буфера общего назначения в данном случае ограничен величиной 65 536 байтов.

В примере Б.3 перед вычислением значений переменных SwpSeg и GenSeg производилась проверка достаточности объема памяти для выполнения задачи. В данном случае распределением памяти занимается DOS, поэтому указанная проверка выполняется иначе.

Контроль выполнения запросов

При описании функций говорилось, что при возврате из DOS состояние С-разряда указывает, успешно или неудачно завершилось выполнение запроса. Контролировать результат выполнения функции 4Ah не имеет смысла, лучше внимательно проверить запись команд, предшествующих обращению к DOS.

Результат исполнения функции 43h надо обязательно проверять. Признак переполнения (c=i) при возврате из DOS означает, что в памяти нет места для размещения блока нужного размера (если исключены ошибки в тексте программы). Что делать в таких случаях?

Выдача аварийного сообщения и прекращение выполнения задачи является самым плохим способом реагирования на недостаток памяти. Всегда можно найти вариант продолжения нормального выполнения задачи. Если освободить место для блока в основной памяти невозможно, то его надо разместить в расширенной памяти, тем более что это никак не скажется на дальнейшей работе с блоком.

Освобождение блоков

Освободившийся блок возвращается DOS по запросу 49h (Free Allocated Memory Block), но с этим действием можно не спешить. В среде DOS задача, как правило, выполняется в монопольном режиме, и кроме нее претендентов на свободную память нет. Перед завершением выполнения задачи освобождать использованные блоки не обязательно. После завершения задачи DOS обязательно освобождает все пространство памяти, которое было за ней закреплено.

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

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.