Программирование в среде Турбо Паскаль (Поляков, Круглов) - страница 120

Существует понятие нормализации адреса. Под этим понимается приведение его к такому виду, что смещение находится в диапазоне от 0 до 15 ($000F). Если вычислен сплошной адрес ячейки памяти, то его можно легко пересчитать в нормализованный «обычный» формат:

СЕГМЕНТ = Сплошной_адрес div 16

и

СМЕЩЕНИЕ = Сплошной_адрес mod 16,

где div и mod — операции деления нацело и взятие остатка от деления соответственно.

Сплошное представление адреса может быть очень большим числом, и мы рекомендуем использовать для его хранения тип LongInt.

- 187 -

10.2. Распределение памяти при выполнении программ


Рассмотрим распределение памяти для выполнимого кода программ на Турбо Паскале (рис. 10.1).

Рис. 10.1

При запуске программы (ЕХЕ-файла) MS-DOS организует в памяти нечто вроде анкеты длиной 256 байт на этот файл, называемой PSP (Program Segment Prefix). Структура PSP описывается в технических руководствах по MS-DOS. Сегмент, с которого начинается отсчет PSP, может быть получен через предопределенную в системной библиотеке (модуле System) переменную PrefixSeg типа Word.

После PSP начинается код ЕХЕ-файла. Он может занимать более одного сегмента. Когда выполняется какой-либо из блоков кода (основной блок, процедуры из модулей), он считается размещенным

- 188 -

в некотором сегменте кода. Реальное значение сегмента при этом содержится в регистре CS процессора.

Статические глобальные переменные основного блока и все типизированные константы, включая локальные, располагаются в сегменте данных, который запоминается регистром DS процессора. Общий объем переменных и типизированных констант не может в сумме превышать 64K.

Заметим, что реальный сегмент может быть и меньше чем 64K. В самом деле, он может начинаться где угодно. Если самый последний байт в нем имеет смещение, например 255 ($00FF), то следующий сегмент может отсчитываться от следующего же байта.

Следом за сегментом данных следует область стека. В ней располагаются локальные переменные и параметры-значения процедур и функций во время их работы по вызову. Сегмент стека содержится в регистре SS процессора. Турбо Паскаль отводит под стек один сегмент, и поэтому область стека не может превышать 64K.

Стек заполняется от своей верхней границы (она может быть назначена директивой компилятору $М) по направлению к началу, т.е. к старту сегмента. Специальный регистр SP процессора содержит смещение указателя стека в сегменте SS (указатель стека — это как бы отметка уровня заполнения стека).


Имеется предопределенная системная переменная StackLimit типа Word, которая логически примыкает к рассматриваемым вопросам. Она содержит минимальное допустимое значение указателя стека. Когда программа запускается, указатель стека имеет максимальное значение, равное отведенной под стек памяти. При работе стек заполняется «сверху вниз», и указатель как бы снижается. Как только он спустится настолько, что свободная часть стека станет меньше чем значение StackLimit, возникнет ошибка времени счета номер 202 Stack overflow (переполнение стека), и программа прервется.