Использование функций DOS
Для того чтобы DOS могла распределять оперативную память, ей надо вернуть все свободное пространство, расположенное за пределами сегментов, образующих тело задачи. Иначе говоря, надо сократить размер блока выделенного для выполнения задачи до ее реальных размеров.
Определение размера задачи
Будем предполагать, что стековый сегмент расположен в теле задачи последним. В таком случае нас интересует расстояние от начала PSP до конца стекового сегмента, выраженное в параграфах. Напомним, что код сегмента, содержащего PSP, находится в регистре es, код стекового сегмента – в ss, а если стек еще не использовался, то его размер в байтах содержится в регистре sp.
Размер тела задачи, выраженный в параграфах, вычисляется так:
tasksize = [ss] – [es] + [sp] /16
В этой формуле квадратные скобки указывают на то, что при вычислении используется содержимое регистров ss, es и sp. При. программировании деление [sp] на 16 заменяется сдвигом на 4 разряда вправо. Для того чтобы не потерять один параграф, размер стека должен быть кратен 16-ти, в противном случае его надо округлить в сторону увеличения.
Зная реальный размер задачи, можно запросить у DOS сокращение ее блока. В результате появится свободное пространство памяти, которое можно использовать по запросам задачи.
Функции DOS
По запросам прикладных программ DOS выполняет несколько функций, связанных с распределением оперативной памяти. Нас будут интересовать только три из них.
Все обращения к DOS происходят через прерывание int 2ih, при этом код запрашиваемой функции указывается в регистре ah, а входные и выходные параметры располагаются в регистрах общего назначения и иногда в сегментных регистрах ds или es.
Функция 48h Allocate Memory выделяет запрашиваемое пространство памяти. Требуемый размер памяти, выраженный в параграфах, указывается в регистре bx. Если такое пространство существует, то при возврате из DOS признак переполнения отсутствует, содержимое bx не изменяется, а в ах находится код сегмента, с которого начинается выделенное пространство памяти. Если свободное пространство нужного размера отсутствует, то при возврате из DOS вырабатывается признак переполнения (устанавливается в 1 С-разряд регистра флагов).
Функция 49h Free Allocated Memory Block открепляет выделенный ранее для задачи блок памяти, после этого задача не может с ним работать. Код сегмента, начиная с которого расположен освобождаемый блок, помещается в регистр es, размер блока указывать не требуется, т. к. DOS хранит его в своей области данных. Если функция выполнена успешно, т. е. блок освобожден, то при возврате из DOS признак переполнения отсутствует. Если он установлен, то наиболее вероятно, что в регистре es был неверно указан сегмент блока.
Функция 4Ah shrink or Expand a Memory Block урезает или расширяет существующий блок памяти. Код сегмента, начиная с которого расположен изменяемый блок, указывается в регистре es, а новый размер блока – в регистре bx. Если функция выполнена успешно, т. е. размер указанного блока изменен, то при возврате из DOS признак переполнения отсутствует. Если он установлен, то блок не может быть расширен или сокращен. В этом случае в регистре bx возвращается наибольший (последний) доступный блок памяти.